← Arquitetura da Casa

Avaliação · jornada

A jornada: câmera → agente → foto → 3D → humano animado

A avaliação não é de um projeto: é da costura. Onde uma palavra muda de sentido de um repositório para o outro, onde um dado é traduzido à mão, onde dois projetos acham que são donos da mesma coisa, e onde a metáfora quebra na passagem.

01 de outubro de 2026  ·  medida pela régua da casa  ·  seis projetos, sete emendas  ·  notas submetidas a contraditório adversarial

24/30soma pela régua
11 / 821medidor de cinco segundos
(arquivos com nome de abstração)
Bcamada que puxou para baixo
(o alcance)
7emendas marcadas no desenho
A linha de montagem do humano animado, em quatro faixas, com as sete emendas marcadas em vermelho.
A linha de montagem em quatro faixas. Cada caixa é um objeto do mundo; cada fio é uma ligação que existe no código, rotulada com o que passa por ela. Caixa vermelha é uma emenda — onde o trabalho troca de mão; fio vermelho tracejado é ligação que o desenho precisa e o código não tem. Abrir em tamanho cheio →

A jornada câmera → agente → foto → 3D → humano animado

Varredura da costura, não dos projetos. Outros tópicos avaliam cada repositório; aqui a obra avaliada é a linha de montagem inteira, e as notas são da JORNADA como peça única. Medida pela régua em REGUA.md. Escrita em 01/10/2026, sobre o trabalho de 30/09. Leitura só: nada foi alterado em nenhum repositório avaliado.

O desenho: jornada.svg — abra primeiro. Ele é o instrumento; este texto é a legenda.


1. A metáfora em uma frase

A jornada é uma linha de montagem de oficina onde um corpo humano é lido de um vídeo, peças são moldadas a partir de fotos, e as duas coisas se encontram numa bancada onde o humano é vestido osso por osso.

A metáfora é real, operante e física — e não é de ninguém. Cada estação a tem por conta própria, e nenhum documento da casa enuncia a linha inteira. O arquivo que mais perto chega é asset-pipeline-dashboard/docs/processos/montar-humano.md, que descreve o processo de montar um humano mas não a jornada que o alimenta: ele começa em "o founder manda fotos" e não menciona o vídeo, o mocap nem o pacote de humano como entradas da mesma obra.

Dentro de cada estação a metáfora é das mais fortes da casa:

A consequência da metáfora não ter dono: as emendas desta jornada não são defeitos de nenhum dos projetos. Cada um fez a sua parte bem, em sua própria oficina, e a linha que as liga não é propriedade de ninguém — nenhum repositório tem um documento, um teste ou um módulo cuja matéria seja a jornada. Isso explica quase todos os achados abaixo: os contratos são bons, as fronteiras são limpas, e o que falha é sempre a costura, que não tem autor.


2. Notas

Notas da jornada como obra, não de cada projeto.

#CritérioNotaEvidência
1Metáfora central2A linha de montagem é operante e física em cada estação, mas nenhum documento da casa a enuncia inteira; docs/processos/montar-humano.md cobre só a metade das peças. ez3d não tem metáfora.
2Fisicalidade da metáfora3esteira, porta, oficina, lixeira, bancada, peça, osso, encaixe, boneco, céu, corredor, molde, ficha — e chega ao nome de arquivo: video-mocap/porta/armazem.mjs, acervo/src/oficina.js:1, maos/territorio.mjs, entrega/boneco.mjs.
3Alcance na estrutura2Chega ao degrau 5 dentro das estações (/api/esteiras, migrations/026_peca_de_humano.sql:127, coluna assets.osso com CHECK de 55 valores, MIME application/vnd.did.acervo.arvore+json) e evapora nas emendas: a fronteira ez3d→acervo é 2 rotas HTTP genéricas; a fronteira video-mocap→player é uma tradução campo-a-campo escrita à mão.
4Linguagem ubíqua2Os conceitos centrais têm nome único e gate que recusa o errado: almost-humanoid/tests/qa-ccp-14-pecas.mjs (88 asserções, rodei: verde) reprova osso em PT-BR na chave, osso inventado e campo desconhecido; acervo/migrations/026:178-196 põe CHECK de 55 valores no banco e test/banco-em-dia.js:99 reprova se o CHECK sumir. A periferia tem sinônimo: encaixe e altura com 2 sentidos cada, e 4 pares EN/PT em acervo/src/peca-de-humano.js (height/above/bone/part).
5Modularidade3Troca real já aconteceu e ficou contida: o motor de captura foi trocado (MediaPipe → SAM 3D Body) dentro de captura/ (video-mocap/README.md:62-66). O estado é o disco (esteira/contrato.mjs:19-33). O ez3d troca de provider de reconstrução por configuração.
6Isolamento3video-mocap/test/modulos.mjs reprova import de qualquer coisa que não seja o produto ou o Node; acervo/src/chave-de-edicao.js:20-26 recusa virar principal de autenticação por raciocínio escrito; ez3d/migrations/011_sem_osso.sql reverteu uma capacidade por posse da afirmação. O contrato mora em terceiro, de propósito.
7Coesão3maos/ são as mãos, juizo/ é o veredito, lixeira/ é a lixeira — e video-mocap/test/ espelha 18 pastas 1:1, incluindo miolo.mjs e mundo.mjs. As gavetas reais são duas e ambas nomeadas: video-mocap/x/ (o nome admite, tem PROVAS.md) e trabalho/ (um filho só). almost-humanoid/spikes/ é tipo de trabalho, com README.
8Objetos a serviço da metáfora2As coisas centrais são coisas: HumanoidPlayer, Ragdoll, SkeletonRig, PoseTimeline, CommandQueue, e no video-mocap e no acervo os objetos são arquivos com nome de peça. Agentes sobrevivem concentrados em dois nichos do almost-humanoid: adaptadores de biblioteca de terceiro (legítimo) e o editor (EffectorManager, AnimationController, PosingEngine).
9Desenhabilidade2O desenho fechou sem inventar peça e sem nenhuma caixa cinza — tudo na jornada tem corpo. Mas exigiu três fios vermelhos (ligações que o desenho precisa e o código não tem) e deixou duas peças invisíveis, a principal sendo o agendador que esteira/esteira.mjs:443 invoca e que não existe. Nota 3 exigiria que as peças sem corpo fossem "poucas e nomeadas"; o agendador não está nomeado em lugar nenhum.
10Ausência de contradições internas2Ver seção 5. Oito contradições têm razão medida e precedência escrita; três são silenciosas, e nenhuma é estrutural. Há inclusive gate cruzado de contrato — acervo/test/contrato-em-dia.js lê o schema canônico de outro repositório e reprova campo a campo.

Soma: 24 / 30.

O medidor de cinco segundos, código próprio (vendor e node_modules fora):

estaçãoarquivos com nome de abstraçãoidentificadores
video-mocap00
asset-pipeline-dashboard05, todos falso positivo (alturaUtil, fonteUtilizavel — substring de palavra portuguesa)
tool-snippets00 (os 52 achados estão em site/vendor/: Tweakpane, GLTFLoader)
ez3d4 em 166 (2,4%)11, dos quais 7 são React Context e 3 são providers/ no sentido do negócio
almost-humanoid7 em 158 (4,4%)23

Jornada inteira: 11 arquivos com nome de abstração em 821 de código próprio. É o número mais baixo que a casa produziu, e sustenta a nota 3 em fisicalidade.

A camada que puxou o resultado para baixo é a B — o alcance. Os critérios 3 e 4 somam 4 de 6 possíveis, e a razão é a mesma nos dois: a metáfora e o vocabulário são fortes dentro de cada estação e governam pouco entre elas. A camada D confirma: o desenho fechou, mas só com fios vermelhos exatamente nas emendas.

Uma nota sobre como estas notas foram fechadas. Rodei um avaliador adversarial contra a primeira versão desta tabela, com instrução de contestar. Ele derrubou três notas minhas, com evidência que eu conferi e aceitei: linguagem ubíqua (eu dei 1 e não vi três gates de vocabulário que existem e rodam), coesão (eu dei 2 contando como gaveta cinco diretórios que o .gitignore exclui — artefato de bancada não é arquitetura) e contradições (eu dei 1 sem contar quantas têm precedência escrita). Três afirmações minhas eram factualmente falsas e estão corrigidas na seção

  1. A soma subiu de 21 para 24, e a correção é do avaliador, não do terreno.

3. O desenho

jornada.svg — a linha de montagem em quatro faixas (a entrada, as duas esteiras, o acervo, a saída), com as sete emendas marcadas em vermelho.

Regras seguidas: cada caixa é um objeto do mundo; cada fio é uma ligação que existe no código, rotulada com o que passa (o vídeo, a foto, o pacote, a malha, as peças, o humano, o item); fio vermelho tracejado é ligação que o desenho precisou e o código não tem; fio cinza pontilhado é dependência documental (lida, não importada).


4. Onde o desenho não fechou

Esta é a seção mais valiosa, e aqui a arquitetura confessa três coisas.

Peça sem corpo — uma, e é a mais importante da jornada.

A própria linha de montagem não tem corpo. Não existe repositório, módulo, documento ou teste cuja matéria seja a jornada inteira. Ela existe como fato operacional — foi exercida o dia 30/09 inteiro — e não existe como peça. Não desenhei caixa cinza para ela porque ela não é uma caixa: é o chão em que as outras estão, e esse chão não está em lugar nenhum. Todas as sete emendas são consequência disso.

Ligações que o código não tem — três, e estão no desenho em vermelho.

  1. Do anexo à esteira. O vídeo que o founder manda chega ao agente como URL, e a foto como caminho local — agnts/supercli/src/format-history.js:88, com a razão escrita (vídeo pesa até 200 MB e o agente raramente precisa dos bytes). A ferramenta que remenda isso existe e é boa: video-mocap/fila/do-topico.mjs baixa o vídeo do tópico e o deposita na entrada. Mas nada a chama: os únicos chamadores no repositório são um teste e o README. O gatilho é o julgamento do agente. (Ressalva honesta: fila/ está formalmente aposentada — ver seção 5 —, então esta ferramenta é de mão por decisão, não por esquecimento. O fio continua vermelho porque a capacidade que ela cobre, "vídeo largado na conversa entra na linha", não migrou para a esteira.)
  2. Da peça ao acervo, com escala. O desenho precisa de um fio levando a escala real do objeto fotografado, e ele não existe: o motor de reconstrução normaliza toda peça para caixa de lado 1 antes do ez3d ver o arquivo, e não há campo de escala original em nenhum dos dois repositórios.
  3. Do humano de volta ao editor. O editor de montagem está construído e o contrato está provado dos dois lados, e eles não se tocam: tool-snippets/site/base/acervo.js:78 exporta sessaoDeEdicao e nenhum arquivo a chama.

Peça invisível — uma, e é do orquestrador vivo.

O agendador da esteira. O produto promete o gesto "grava uns segundos no celular, larga, e de manhã está pronto", e a janela 01:00–07:00 está codificada. Mas quem acorda à 01:00 não está em lugar nenhum da jornada. A própria esteira o invoca sem o ter — video-mocap/esteira/esteira.mjs:443: "UMA RODADA sobre todos os trabalhos da raiz. É o que um agendador chama." Grepei cron, systemd, timer, agendador em esteira/, entrada/, did.json e server.js: não existe.

O agravante é que havia um e ele foi removido com boa razão: entrada/da-porta.mjs:13-22 conta que a porta tinha um timer de cinco minutos dentro do próprio processo do servidor, e que esse timer era um segundo orquestrador com lista de etapas própria. Tirá-lo foi acertado; o substituto ficou fora do repositório. O desenho da jornada tem uma seta que entra na esteira vindo de fora da folha.

Uma segunda, menor: o runner de provas pesadas (heavy run --gate) que video-mocap/x/PROVAS.md usa é peça de infraestrutura da casa que o desenho das provas precisa e que não vive em repositório nenhum da jornada.


5. Contradições

Internas (dentro de uma estação)

Nenhuma relevante. É notável e merece ser dito: as contradições desta jornada são todas de fronteira. Cada estação é internamente coerente.

Com os vizinhos

As silenciosas — três. São as que custam.

(a) Dois implementadores do contrato do humano, e o dono não é quem monta. Tipo 1.

Quem deveria ganhar: o almost-humanoid, porque ele já declarou a posse e já escreveu o validador. Mas a promessa não é cumprível hoje por um motivo estrutural que ninguém nomeou: o almost-humanoid é "private": true e não declara exports; só o subpacote packages/player é importável, e o contrato (src/envelope/) está fora dele — confirmado: packages/player/src/proporcao-runtime.js não importa src/envelope/ uma única vez. O contrato não tem porta de saída. É isso que precisa nascer primeiro.

Já custou uma vez: pecas.ossos, escrito pelo acervo, era recusado pelo próprio contrato da casa com PECAS_FIELD_UNKNOWN — "o manifest publicado do boneco de massinha era recusado pelo próprio contrato da casa" (CCP-MANIFEST-1.5.md:278-284).

(b) Um campo de contrato que ninguém escreve e ninguém lê — e ele é o meta, não a procedência. Tipo 2.

O relato que pediu isso foi fechado quando a spec criou o campo (CONTRATO.md:385), e a costura não mexeu em nenhuma das pontas. Quem deveria ganhar: o campo oficial, e a dívida já está declarada em CONTRATO.md:360-363.

Correção de uma afirmação que eu fiz e estava errada. Eu havia escrito que o procedencia.json é "lido por ninguém". Não é, e em duas camadas. Existem dois arquivos diferentes com esse nome na jornada: o do ez3d, que o acervo ingere como peça dado do item (acervo/src/ferramentas.js:85-89 — "é o que permite auditar de onde um modelo veio sem ter que voltar ao banco do EZ3D"; a rota em src/routes/ferramentas.js:131-144, provado em test/integracao-ez3d-sync.js:177); e o do video-mocap, que é lido dentro do próprio projeto por teto/medir.py:80, para saber se um refino já foi aplicado antes de medir. Esse leitor nasceu de um incidente que vale citar, porque é o oposto de dívida: medir um pacote já refinado e chamar o resultado de cru produziu um número publicado falso (1,93 cm contra os 2,85 reais), e medir.py:66-77 registra isso — "Medida que engana é pior que medida ausente." O que de fato não atravessa a fronteira é a procedência por clipe rumo ao anim.library[].meta, que é a contradição acima.

(c) Um sinônimo inventado na emenda, que não vem de ninguém. Tipo 5.

Quem deveria ganhar: o português, que é o contrato. O alias em inglês é tolerância defensiva contra um emissor que não existe, e tem custo medido: o tool-snippets lê só a forma portuguesa (site/bancada/bancada.js:97), então um humano escrito na forma fit seria lido pelo acervo e invisível para o editor.

As declaradas — com razão escrita e precedência. São oito, e é por elas que o critério 10 fica em 2 e não em 1.

contradiçãotipoos dois ladosquem ganha, e está escrito
O contrato em 3 versões vivas2video-mocap/pacote/montar.mjs:80 escreve 1.3 · acervo/src/humano.js:248 lê 1.4 · almost-humanoid/src/envelope/manifest.js:112 é 1.5Ninguém precisa ganhar: a régua de aceitação compara só o MAJOR, de propósito (manifest.js:479). Um 1.3 passa no validador 1.5.
A cópia datada defasada3video-mocap/pacote/CONTRATO.md:3 lida contra 1.4 · spec em 1.5A cópia datada existe para tornar isso visível, e funcionou (CONTRATO.md:3-11). Um dia de atraso num contrato nascido ontem.
pecas.ossos × proporcao.ossos2acervo/docs/tipos-da-casa.md:473-498 escreve no endereço antigo · almost-humanoid/src/envelope/proporcao.js:578-595 migra na leituraproporcao.ossos vence, escrito em proporcao.js:584-588, com migração automática do endereço legado.
altura/acima × encaixe4acervo/src/peca-de-humano.js:444 · acervo/src/humano.js:262encaixe vence, em código (public/vendor/visor-humano.js:626-629, com o motivo: "são duas descrições da mesma coisa, e aplicar as duas somaria dois deslocamentos") e em doc (tipos-da-casa.md:451-454).
encaixe com dois sentidos5acervo/docs/processos/montar-humano.md:48-50 (a entrada do osso) · acervo/docs/tipos-da-casa.md:415 (a pose dentro dela)Não decidido — mas a colisão está registrada entre parênteses pelo próprio projeto. Um dos dois precisa de outro nome.
height/above/bone/part aceitos ao lado dos nomes em português5acervo/src/peca-de-humano.js:444-445, :286-287O português vence, e a tolerância tem razão escrita em :281-284: "Aceita bone tambem porque o contrato do almost-humanoid e escrito em ingles, e um exportador de la vai escrever bone antes de escrever osso." Tolerância de fronteira declarada é diferente do fit órfão acima, que não tem emissor nenhum.
VRM_MINIMO copiado da especificação2video-mocap/animacao/canonico.mjs:136 · a lista canônica no almost-humanoidA cópia vence localmente, por decisão escrita: "é cópia de propósito: o desacoplamento manda que este produto não importe código de lá. Se a especificação mudar, muda aqui, e o relato diz quem mudou" (canonico.mjs:132-134).
Dois orquestradores do mesmo pipeline1video-mocap/fila/rodar.mjs (varria pasta, janela da madrugada) · video-mocap/porta/rodada.mjs (timer de 5 min no servidor)A esteira vence, e a resolução é modelar: fila/APOSENTADO.md põe os dois lado a lado numa tabela, nomeia o dano ("o mesmo vídeo entrando por caminhos diferentes saía com um conjunto diferente de etapas") e existe "para que ninguém precise ler os dois fluxos para entender qual é o de verdade". É a contradição mais cara possível — tipo 1, dois donos do mesmo processo — resolvida e documentada.

E duas que não são contradição, e merecem registro invertido.

O gate do osso que cede. A regra "um clipe não pode animar a translação de um osso que a proporção move" é executável em três lugares com severidade decrescente, e a graduação é argumentada: acervo/scripts/monta-boneco-de-massinha.js:637-641 lança e aborta a montagem; almost-humanoid/src/envelope/proporcao.js:545-552 lança PROPORCAO_OSSO_ANIMADO com escopo maior; packages/player/src/proporcao-runtime.js:609-634 apenas avisa, porque "o player recebeu um glb que já está no ar, e derrubar o humano inteiro por um conflito entre dois campos dele deixaria o host sem nada na tela" (:598-602). Severidade que decresce conforme o dado se afasta de quem pode consertá-lo é o melhor padrão de fronteira da casa, e é o modelo das ações abaixo.

O gate cruzado de contrato, que existe e eu afirmei que não existia. acervo/test/contrato-em-dia.js lê o schema canônico de outro repositório do disco — e, quando o disco não o tem, da URL publicada no $id da própria cópia, explicitamente porque "na VM e em qualquer CI o teste PULAVA — passava verde sem ter conferido nada, que e o pior estado possivel pra uma sentinela". Compara caminho e valor campo a campo, nomeia o caminho exato do que divergiu e sai com código 1. Roda no corredor (test/corredor.js:81). Nasceu de um incidente datado de 27/08/2026, em que três campos divergiram em silêncio. Esse gate é o molde pronto para a ação 5.


6. Ações propostas

Ordenadas por nota que movem por hora gasta. As três primeiras constroem gate; é deliberado.

#AçãoHorasCritérioDe → para
1Apagar o alias fit e os três irmãos (position, rotation, scale) de acervo/src/humano.js:314-318: nenhum produtor os escreve, e o validador do dono do contrato já lança neles (almost-humanoid/src/envelope/pecas.js:165, ENCAIXE_FIELD_UNKNOWN). O acervo está tolerando o que o contrato recusa. Distinguir dos pares height/above/bone/part de peca-de-humano.js, que têm emissor real e razão escrita — esses ficam.1 h4, 10sustenta 2 em 4
2Escrever a frase da jornada num docs/a-linha.md do acervo (ou do almost-humanoid), nomeando as estações, o que passa entre elas e quem é dono de cada contrato. É a peça sem corpo da seção 4.2 h1, 92 → 3
3Dar porta de saída ao contrato: exports no almost-humanoid expondo src/envelope/ (ou mover pecas.js/proporcao.js/canonical-bones.js para dentro de packages/player, que já é publicável). Sem isso, a promessa escrita em CCP-MANIFEST-1.4.md:146-148 não é cumprível.3 h6, 10mantém 3 em 6; destrava a ação 4
4O acervo importa a regra em vez de reimplementá-la: trocar a leitura de manifesto de src/humano.js e a validação de src/peca-de-humano.js por validatePecasShape/validateProporcaoShape do contrato. Fecha a contradição (a) e leva o acervo de CCP 1.4 para 1.5 de graça — que é o que a proporção pedida ontem precisa.5 h10, 42 → 3 em 10
5Um gate cruzado de nome de osso, no molde que a casa já tem: acervo/test/contrato-em-dia.js lê o schema canônico de OUTRO repositório do disco (ou da URL publicada, quando o disco não tem) e reprova campo a campo. Copiar esse molde para comparar as quatro cópias do mapa Mixamo↔VRM, e a lista OSSOS de acervo/src/peca-de-humano.js contra CANONICAL_SET do contrato. Hoje são idênticas por disciplina; o teste converte disciplina em estrutura.3 h4, 102 → 3 em 4
6Declarar a unidade na fronteira do ez3d: escrever extras.unit (ou unitScale) no depósito ao acervo, mesmo que seja para dizer "normalizado, sem escala real". O acervo já tem o mecanismo de leitura (src/medidas.js:47-75) e hoje cai sempre no palpite por ordem de grandeza. Para de registrar cabeça de massinha com um metro.2 h3, 102 → 3 em 3
7Desempatar encaixe: escolher outro nome para um dos dois sentidos. O da entrada do osso é o que tem alternativa fácil na casa ("o posto do osso", "a vaga"); o do manifesto é contrato publicado e deve ficar. A colisão já está registrada em montar-humano.md:48-50; falta decidir.2 h4sustenta 2 em 4

O que deliberadamente não propus: ligar o editor de montagem (emenda 7). Não é dívida arquitetural — é trabalho de produto em curso, e o próprio editor declara que está esperando escolha de layout, com uma frase que merece ser política da casa: "Uma ferramenta que parece pronta e não salva é pior que uma que avisa" (tool-snippets/site/f/editor-de-humano/index.html:19-20). Também não propus agendar do-topico.mjs: é decisão de operação, não de arquitetura.


7. O que eu não consegui avaliar