Roteiro

rascunho 22 min de leitura 4.283 palavras Editar no GitHub

Status: proposta. Substitui nada — as sessões S1 a S6 da spec do motor continuam válidas no que não conflita. Data: 2026-08-28 Depende de: VISION.md, kinds.md e depth.md

Ordenado por o que destrava o quê, não por facilidade nem por empolgação. Cada fase tem critério de saída verificável; fase sem critério é intenção.

Onde as fases desembocam (revisto em 19/10/2026). O que o leitor vê não é uma fase, é um handbook com roadmap · artigos · labs, que pode combinar fluxos, estado/reconciliação e manipulação direta. A F4 entrega otel.model; a F6, cpu.model; a F6b, o ATmega dentro do segundo. O catálogo que a capa consome manifestos handbooks/<id>/handbook.yaml, além dos legados TypeScript em apps/site/src/data/handbooks.ts. O Studio edita fontes sem alterar motores; a entrega une conteúdo e host compilado por contratos explícitos. O capítulo Runnable handbook deliveries registra a primeira implementação e seus limites. As fases abaixo preservam o roteiro do motor composicional; elas não bloqueiam autoria e distribuição independentes.


F0 — Destravar

Sem código. É a fase mais curta e a que mais importa.

ItemPor que trava
LICENSE (Apache-2.0) e LICENSE-content (CC BY-SA)Repositório público sem licença é, por padrão, todos os direitos reservados. Hoje ninguém pode reusar nada, o que contradiz a intenção do projeto
Decidir entrega-1 contra mainA branch default envelhece mal e confunde quem chega
Nomenclatura do pacoteSufixo de arquivo é a coisa mais difícil de mudar depois que existe ecossistema (VISION.md §9.6)
Unidade de recursoSe sair MB e vCPU, a ferramenta será usada para dimensionar, que é o que ela não é (§7.2)

Saída: os quatro decididos e registrados em ADR.


F1 — Núcleo: as cinco mudanças que não podem ser feitas depois

Recurso, backpressure, transformação, controle e fases do tick mexem no contrato de comportamento. Fazer depois de existirem arquétipos e pacotes significa reescrever todos.

São uma fase só de propósito. Contenção de recurso é backpressure; separar produziria dois mecanismos concorrentes para o mesmo fenômeno.

MudançaOnde
Emissão que pode falharBehavior deixa de devolver out presumido; passa a saber o que foi aceito
Capacidade e política no canalWire ganha capacidade e política de recusa (bloqueia, descarta novo, descarta velho)
Regime propagando para trásO estado “bloqueada” sobe a cadeia
Recurso como portaarbiter como folha; pedido e concessão viram tráfego de porta, e o medidor segue honesto
transform como arquétipoSai do channel e do sink. A carga muda em um lugar só
Semântica da linha de controleSinal entregue muda o que o ator faz naquele tick, contado no livro-caixa como tráfego e nunca como carga. Hoje Wire.line: "control" é desenho: resolveTarget a ignora
Fases do tickUm tick passa a ter acomodação (ponto fixo do subgrafo combinacional) e confronto (entrega do que atravessa aresta registrada)

Por que as duas últimas entraram aqui, em 29/08/2026. Elas vieram da CPU (F6), e a tentação era deixá-las lá. Mas as duas mudam a assinatura de Behavior e o significado de um tick — que é exatamente o critério desta fase. Uma linha de controle que muda comportamento obriga o ator a receber sinal além de carga; fases do tick mudam o que “um passo” quer dizer para todo arquétipo já escrito. Chegar na F6 com trinta arquétipos e descobrir isso é o retrabalho que esta fase existe para evitar.

Saída:

  • A perturbação da janela do receptor fechando derruba dado por emergência, sem roteiro
  • Estourar memória mata o bloco e perde o que estava retido
  • O property test do invariante visual passa: nenhuma aresta tem carga de forma diferente nas duas pontas, exceto saindo de transform
  • seek continua exato com eventos de parâmetro e de recurso no histórico

Saída acrescentada pelas duas mudanças novas:

  • Um sinal de controle chega, muda a decisão do ator no mesmo tick, e aparece no livro-caixa — sem nunca ser contado como carga
  • Um caminho puramente combinacional resolve dentro de um tick; um que atravessa aresta registrada custa um tick. Os dois são visíveis, e a diferença entre eles é visível
  • Laço combinacional é recusado na construção do mundo, com o ciclo nomeado. Em hardware ele é erro de projeto; aqui seria ponto fixo que não converge, ou seja, trava

Risco: já se materializou, e a resposta já é conhecida. Esta fase sempre foi “a que pode revelar que a arquitetura de tick único não aguenta”. A CPU revelou antes de a fase começar: tick único não distingue o que fecha dentro de um ciclo do que atravessa um registrador. A saída não é abandonar o mínimo de um tick por aresta — é dar fases ao tick, que é como simulador de lógica síncrona já funciona (os delta cycles de VHDL e Verilog) e é a distinção que CPN faz entre transição imediata e transição temporizada. Detalhe em theory.md §7.5.


F2 — Prova do motor: o que já está planejado, e basta

Corrigido em 28/08/2026. A versão anterior desta fase propunha um “lab de prova” mínimo — a fila enchendo. Era redundante: a spec do handbook (docs/superpowers/specs/2026-08-28-otel-visual-handbook-design.md §10) já tem a prova em dois estágios, e melhor desenhada.

EstágioO que éPapel
Hero da Entrega 1Mini-simulação real embutida na landing, sobre depth-core e otel-domain de verdadePrimeiro teste do motor, sem depender do motor completo
Piloto da Entrega 2Anatomy of a Trace com os quatro níveis, mais o anexo W3C Trace ContextProva da profundidade. Nasce com os quatro porque prova parcial não prova nada

Nada a acrescentar aqui. A correção que este documento precisava era retirar uma fase, não inventar outra.

F2.1 O que o piloto exige de verdade

E uma estimativa deste plano precisa ser corrigida junto. A afirmação de que “o primeiro lab não exige nenhum arquétipo novo” valia para o lab da fila, não para o piloto:

NívelO que exige
L0 · FlowO que já existe
L1 · MechanismCapacidade e política — F1
L2 · WireCanal abrível. O enquadramento HTTP/2 mora dentro do channel
L3 · PayloadCarga abrível. O documento OTLP como objeto com interior

L2 e L3 são o custo real do piloto, e são também o diferencial (why-simulate.md §14).


F3 — Palco

Adotar React Flow antes de investir em desenho próprio (stack.md §1).

ItemNota
Nós aninhados com parentId e extent: "parent"É a moldura com clamp, de graça
Handles como portasEntrada, saída, descarte, e as portas de controle
Duas espécies de linhaDado em traço grosso, controle em tracejado fino (kinds.md §1.1)
Foco por caminho, breadcrumb, selecionar contra abrirJá especificado na §4 da spec do motor
Deep link com semente, foco, tick e seleçãoSem a semente na URL, o handbook não pode apontar para um fenômeno

Saída: abrir o provider, descer até a fila, selecionar uma carga, avançar, e ver a forma dela mudar ao atravessar o transform — tudo por smoke automatizado.


As vistas fundas passaram a ser medidas — 2026-09-08

profundidade.spec.ts mede o espaguete um nível abaixo de cada lab, que é onde ele estava: a vista da ULA tinha 342 cruzamentos e 2345 sobreposições enquanto o lab passava com teto quinze. Três causas, e a pior era a key do React repetida entre fios agregados — nó órfão acumulando a cada tick, invisível para toda medida que olhava o modelo em vez da tela. Registro em docs/PROGRESS.md (Entrega 9).

Próximo alvo do desenho: a porta lógica é desenhada com o trapézio do seletor e não seleciona nada; a forma tem de seguir o leque real. E o processador do micro, com 42 cruzamentos, é a vista mais cara que sobrou.

A linguagem visual ganhou o túnel — 2026-09-08

Onde dois fios se cruzam, um mergulha e reaparece, com uma boca em cada ponta. Fecha a metade que a convenção do pontinho de junção respondia por ausência. O vazio é máscara e não d partido, então a medida de espaguete não perde um cruzamento de vista — os cinco tetos passaram sem mudar. Registro em docs/PROGRESS.md (Entrega 7).

A rodada seguinte do desenho é soltar os pesos do roteador (com cruzamento legível, cruzar ficou barato) e as quatro figuras aprovadas: carga na esteira item a item, esteira entupida, alerta na máquina, camada de circuito.

F4 — otel como primeiro pacote de modelo

Aqui o projeto deixa de ser motor e passa a ser produto.

O primeiro lab está no ar — 2026-09-01

labs/providers publicado: os três provedores do SDK, com L0, L1 e L3, e o invariante do envelope provado por property test mais teste de mutação. A linha “árvore fiel do TracerProvider” da tabela abaixo está feita; o importador de manifesto, a leitura da configuração nativa e o contrato de fidelidade no CI continuam abertos. Registro em docs/PROGRESS.md.

A contraparte real deixou de ser pendência — 2026-09-08. labs/providers/ existe e roda: app Java com o SDK fixado (BOM 1.65.0), Collector imprimindo, compose.yaml. Foi rodada de verdade — 56 spans em lotes de cinco segundos, service.name chegando uma camada acima dos spans, escopo checkout.http no meio. Com ela veio a seção Instrument it, e o bloco certo de cada exercício é extraído daquele arquivo, nunca escrito ao lado.

O retorno de motor deste round: o router estava descrito de um lado só — o texto do catálogo descreve o mux, que escolhe qual entrada responde, e um amostrador é o espelho disso. Fica registrado sem kind novo: a régua exige dois alvos pagantes, e há um.

ItemNota
Árvore fiel do TracerProviderCada objeto com âncora na spec oficial
Importador de manifesto, três camadasEsqueleto do compose, recheio por resolvedor de imagem, ajuste por environment e arquivo montado (VISION.md §5)
Leitura da configuração nativaO mesmo YAML do Collector, não formato inventado
Contrato de fidelidade no CITodo parâmetro resolve para ajuste real documentado, com link que o CI verifica
Validação contra o realO mesmo arquivo roda no modelo e no labs/<slug>/, e os dois concordam qualitativamente

Saída: despachar um compose com Collector e receber o modelo montado, sem edição manual. Serviço sem pacote aparece como bloco opaco declarado, nunca como caixa vazia.

Risco: é a fase onde a fidelidade é ganha ou perdida. Se o modelo e o lab real discordarem e a discordância for resolvida ajustando o modelo para parecer certo, o projeto virou teatro.


F5 — Handbook gerado da travessia

Cada objeto já carrega explicação com âncora. O handbook é uma ordem de visita sobre a árvore, não um documento paralelo.

Saída: a página do lab é gerada do modelo, e mudar a árvore muda a página. Nenhum texto técnico sem link para a fonte.


F6 — CPU: onde o motor amadurece

Um caminho de dados de CPU, com assembly como entrada e drill-down até a porta lógica. Detalhamento completo em theory.md §7.

Tem público, e isso muda o peso da fase. O Luigi declarou em 29/08/2026 que este alvo é material para as aulas do pai dele: um modelo com entrada especial, que se programa em assembly, para ensinar arquitetura de computadores. Deixa de ser só a prova de que o motor é genérico e passa a ser uma entrega com destinatário — e um leitor real, que não é o Luigi, é a coisa mais escassa que um projeto assim tem.

Decidido em 29/08/2026 pelo Luigi: a CPU passa na frente do Kafka. Dois motivos, e o segundo é o que decide. O primeiro é que ela tem público e o Kafka não. O segundo é que extrair o motor tendo visto só domínios de mensageria — OTel e Kafka — é extrair um motor de mensageria com outro nome. A CPU é o alvo mais distante que ainda cabe nas primitivas, e é justamente por isso que ela é o teste; o Kafka, colado no OTel, quase não pressiona a abstração.

Revisto no mesmo dia, e é uma inversão de verdade: a CPU passa também na frente do OTel (F4 e F5). A versão anterior desta linha dizia o contrário — que furar essa ordem faria o projeto perder o alvo que lhe dá nome. O argumento do Luigi que a derrubou:

“o otel é bom mas vai precisar de bastante trabalho e refinamento, para isso quero amadurecer mais o motor com o .model da cpu”

E ele está certo sobre a natureza dos dois trabalhos. O que falta no OTel é sobretudo editorial — currículo, texto, procedência, fidelidade a uma especificação enorme —, e esse trabalho não pressiona o motor; ele consome tempo enquanto o motor fica igual. A CPU é o oposto: pouquíssimo texto, e uma verdade de campo dura e verificável (uma ISA executa um programa ou não executa). É o alvo que amadurece o motor por unidade de esforço, e amadurecer o motor é pré-requisito de o OTel ficar bom, não concorrente dele.

O risco disso, dito em voz alta: o projeto se chama OTel Visual Handbook e acaba de adiar o OTel. Se a CPU virar o produto, o projeto trocou de identidade sem decidir trocar. A trava contra isso é um critério de reentrada declarado, e não força de vontade:

A F6 termina — e o OTel recomeça — quando as cinco mudanças da F1 estiverem fechadas e o cpu-domain rodar um programa de verdade sem que depth-core tenha ganhado uma linha que saiba o que é um registrador. Amadurecer o motor é o objetivo; construir um simulador de arquitetura de computadores completo não é, e a hora de parar é a hora em que a próxima tarefa da CPU não ensina mais nada ao motor.

Ela nomeou seis lacunas do motor — três previstas e três que só a construção achou —, todas legítimas e nenhuma resolvível com um kind novo. Todas fechadas em 29/08/2026:

LacunaO que faltavaOnde fechou
Linha de controle sem semânticasinal muda o que o ator faz no ciclo, contado como tráfego e nunca como cargasigin:, ctx.signals, toPort obrigatório
Ler sem consumirbanco como ator que responde a pedido — nenhum ator espia o estado de outroo banco responde; a escrita do tick já vale para a leitura dele
Combinacional × registradoo tick ganha fases: acomodação em ordem topológica, depois o que atravessa a bordaWire.timing, settle × clocked
A acomodação era invisível de forao livro-caixa contava quantas mensagens saíram, nunca o que diziamWorldState.settled
Não havia fonte constante da acomodaçãoum trilho de alimentação não recebe nada e precisa dirigir dentro do tickObjectSpec.drives, com as duas mentiras recusadas na construção
Bornes não compunhama expansão abria uma camada e a carga caía no terminal errado, caladaexpansão recursiva, Borne = string | { node, port }

E uma menor, ainda aberta: escala de tempo é do mundo, não do motor — 100 ms no OTel, ~0,3 ns na CPU. A constante vira propriedade do WorldSpec, com unidade.

O critério de reentrada foi atingido — 2026-08-29

As três condições, com a evidência de cada uma:

  • As mudanças da F1 fechadas — as cinco previstas e mais três achadas no caminho.
  • cpu-domain roda programa de verdade — RV32I, montador com erro em linha e coluna, diferencial instrução a instrução, 484 testes unitários e 78 e2e verdes.
  • depth-core não sabe o que é um registrador — pnpm boundaries verde em 60 arquivos, e nenhuma das seis mudanças acima usa vocabulário de CPU.

A fatia vertical desceu até o fim: circuito › bit0 › XOR › NAND › PMOS, oito níveis, com o somador de 4 bits rodando em transistores de verdade.

E o sinal de parada apareceu. O que sobrou da CPU — abrir a unidade lógica (deslocador, comparador, lógica bit a bit) — é o mesmo trabalho do somador repetido em outro caminho, e não ensina nada novo ao motor. Ela fica folha, e isso está declarado no arquivo. Pela regra escrita acima, é aqui que se para.

Fica uma decisão de ordem para o Luigi, e ela não é nossa: a linha de ordem manda F6 → F6b (ATmega) → F4 (OTel), e o critério de reentrada diz que o OTel recomeça no fim da F6. O ATmega traz interrupção — controle assíncrono que preempta o fluxo, o primeiro fenômeno que talvez não caiba nas primitivas —, então ele ainda ensinaria o motor; mas ele também é mais um passo antes do alvo que dá nome ao projeto.

Saída: um pacote cpu-domain que importa exclusivamente depth-core e depth-ui, executa um programa em assembly de verdade, abre até a porta lógica, e não obrigou depth-core a saber o que é um registrador. Commits em depth-core fechando as três lacunas contam a favor; vocabulário de CPU dentro dele reprova.

F6c — O microprocessador genérico, feito em 30/08/2026

A F6 tinha parado pelo critério certo: o que sobrava da CPU não ensinava mais nada ao motor. Mas o critério mudou — passou a ser “abrir isto ensina algo a quem lê” —, e um modelo de terceiro apareceu para pôr as duas perguntas à prova de uma vez.

Reconstruímos no motor o microprocessador genérico do deck de Prof. Filippo Valiante Filho (usado com permissão): máquina de acumulador de 8 bits, multiciclo, ao lado do RISC-V e antes dele no mapa. O que ela traz e o ciclo único não tinha é o ciclo de instrução como tempo — um tick é um micro-passo, não uma instrução.

Ela ainda ensinou o motor, contra a previsão: nasceu kind: "sequencer", o primeiro da família controller, porque uma UC multiciclo é máquina de estados e router não guarda estado. E ensinou muito a quem lê: a tabela de tempo do slide 43 do professor virou oráculo, e as onze linhas bateram célula por célula.

O que isso reposiciona: a frase “o motor instancia modelos e lhes dá profundidade” deixou de depender de modelos que nós mesmos desenhamos. O deck para na ULA, porque slide não abre; nós descemos dali até o transistor, nove níveis, sem uma linha de domínio nova em gates.ts ou transistors.ts.

A decisão de ordem da F6 segue aberta e é do Luigi: F6b ATmega ou F4 OTel. O que mudou é que a F6c já entregou parte do que a F6b ia buscar — fidelidade verificável contra um documento que não controlamos — sem gastar um datasheet inteiro. O que a F6b ainda tem de único é a interrupção.

F6b — ATmega: a fidelidade posta à prova

Pedido pelo Luigi em 29/08/2026, depois de a CPU genérica estar bem feita. Um AVR de 8 bits (o ATmega328P é o candidato óbvio: é o do Arduino Uno, tem datasheet público e detalhado, e é o chip que mais gente já viu).

Os dois alvos testam coisas diferentes, e é por isso que os dois valem:

A CPU genérica testaO ATmega testa
Mecanismo — o motor consegue expressar caminho de dados, controle e ciclo?Fidelidade — o modelo bate com um chip real, num nível em que a discordância é objetiva?
A verdade de campo é uma ISA que a gente escolheA verdade de campo é um datasheet que a gente não controla
Erra-se por incapacidade do motorErra-se por o modelo ser mais simples que o mundo — e aí o not_modeled precisa dizer isso

E ele pressiona coisas que a CPU didática não tem, cada uma um candidato a lacuna nova:

  • Interrupção — controle assíncrono que preempta o fluxo. O motor hoje não tem nada que interrompa o que está acontecendo; é o primeiro fenômeno da lista que talvez não caiba nas primitivas atuais, e por isso é o mais valioso de tentar.
  • Periférico mapeado em memória — temporizador, GPIO, USART, ADC. Escrever num endereço faz uma coisa acontecer no mundo, o que é um efeito colateral endereçado.
  • Harvard — programa e dados em memórias separadas, com barramentos separados. Bom contraste com a von Neumann do alvo anterior, e de graça: é a mesma peça em outra topologia.
  • Pinos — a fronteira do chip com o lado de fora vira porta de verdade.

Sinal a observar, não critério: quantas lacunas novas do motor o ATmega abre depois da CPU genérica. Zero significa que o motor amadureceu. Cinco significa que ele estava sendo derivado do primeiro alvo, e aí o problema é do motor, não do ATmega.


F7 — Kafka: o terceiro alvo

Revisado em 28/08/2026. Era “o teste da tese do projeto”, medido pelo custo relativo do segundo pacote. Com o corte de escopo que fez cada model ser ilha (why-simulate.md §9), reuso deixou de ser requisito — logo, deixou de ser critério de saída. O Kafka volta a ser simplesmente mais um alvo.

Arquétipos da onda 2: log, deliver, supervisor.

Saída: o model do Kafka existe, com handbook próprio, e o log ensina atraso por leitor — o fenômeno mais estranho ao TracerProvider, e o que justifica o Kafka continuar na lista.

O que continua valendo observar, agora como informação e não como nota de aprovação: quantos arquétipos novos o Kafka exigiu além dos três previstos. Um ou dois é normal. Cinco significa que o catálogo está sendo derivado caso a caso — e aí o problema é do catálogo, não do reuso.


F8 — Extração do motor

Só depois de F6 e F7. Motor extraído antes de dois casos completos fica genérico e inútil, e motor sem conteúdo não atrai ninguém em open source.

Nesta fase entram o contrato de plugin, o pacote publicável e a decisão do repositório próprio.


Como medir se está dando certo

SinalBomRuim
Arquétipos novos por alvoCai a cada alvoConstante ou crescendo
modelet por fenômenoMenos modelet que fenômenoTrinta modelet para oito fenômenos é reimplementação (why-simulate.md §3.1)
Parâmetro sem procedênciaZero, garantido por CI“Depois a gente ancora”
Fenômeno que precisou de roteiroZeroQualquer um
Tarefa da CPU que não ensina nada ao motorÉ o sinal de parar e voltar ao OTelFazer mesmo assim, porque é divertido
Discordância entre modelo e lab realResolvida corrigindo o modelo ou declarando o que não é modeladoResolvida deixando o modelo bonito

O quarto é o mais importante. No dia em que um fenômeno precisar ser roteirizado para aparecer, o projeto deixou de ser simulação e passou a ser animação — e nenhum dos outros sinais importa mais.

Onde a autoria assistida entra, e onde não entra

O Luigi quer usar IA em peso na produção de pacotes. Isso funciona com portão e é perigoso sem, porque o único ativo do projeto é a fidelidade e geração assistida produz texto plausível (VISION.md §9.3).

Entra bemNão entra
Rascunhar a composição de um pacote a partir da documentação oficialEscrever comportamento de arquétipo sem revisão
Levantar e organizar fontes antes de escreverSer a fonte de uma afirmação técnica
Propor a ordem de ensino de uma trilhaDecidir o que é fiel
Encontrar divergência entre o modelo e a documentaçãoResolver a divergência sozinha

O que torna isso seguro é a §4.1 da visão: pacote é dado validado por schema. Compor dado errado é localizável e difável; comportamento errado escondido numa função, não.

Ordem, em uma linha

F0 destravar → F1 núcleo → F3 palco → F2 piloto (Entregas 1 e 2) → F2b arquétipos
  → F6 cpu → F6b atmega → F4 otel → F5 handbook → F7 kafka → F8 motor

Os identificadores de fase são nomes, não sequência — F3 sempre veio antes de F2, e desde 29/08/2026 a F6 vem antes da F4. Quem manda é a linha acima.

O piloto e o palco se sobrepõem: não há lab sem palco, e o palco só se justifica pelo lab. E a onda de arquétipos vem depois do piloto, porque o piloto revela quais são realmente necessários.

A CPU vem antes do OTel porque amadurece o motor por unidade de esforço, e o motor maduro é pré-requisito de o OTel ficar bom. O critério de reentrada está na F6, e existe justamente porque essa ordem é a que mais facilmente vira desvio permanente.

O playground (why-simulate.md §10) não é fase: ele nasce de graça ao fim de F3, porque é a mesma paleta e a mesma engine, sem exigência de procedência.

Nenhuma fase começa antes de a anterior ter fechado o critério de saída. O sinal de alarme mais confiável do projeto é começar o Kafka antes de o OTel estar fechado.