id: "REQ-286" title: "Choques do atualizador sem falsos positivos: artefatos de sistema fora do diff, divergência nunca escondida e decisão em lote" status: "implemented-pending-homologation" date: "2026-10-20" author: "executor" target_repo: "conn2flow" batch: "BATCH-295" topology: "dupla" autonomy: "autonomo_monitorado" origin: "Pedido do Engenheiro Chefe durante a REQ-285 (BATCH-294), depois das atualizações 3.0.9 → 3.0.11 e dos deploys do conn2flow-site no Lab"
req-286: Choques do atualizador sem falsos positivos
1. O relato
Na REQ-285 o Lab ([REDACTED], core + conn2flow-site) acumulou 1.423 choques numa única atualização, e o deploy do projeto produziu mais 298. Quase todos eram falsos positivos: arquivos regravados por sincronizações de teste (project:sync-core / sync-files de 19/10), fora das entregas, que o manifesto passou a ver como "editados no servidor". Ninguém consegue decidir mil choques na tela, um a um. E o que importa — a divergência real — some no meio.
Pedido do Engenheiro Chefe: os arquivos de sistema (ex.: vendor/, vendor/composer/installed.php) não devem passar pelo diff/choque. Choque é para o que alguém pode ter mudado à mão; principalmente o que é do core.
2. O que foi encontrado (dados do Lab, 2026-10-20)
-
Artefatos gerados viram choque. Entre os choques:
vendor/composer/installed.php(só muda o hash do commit),*.precompiled.cssde módulos (169 KB cada, um por página e idioma),assets/asset-versions.json,assets/modulos/covers/manifest.json,db/data/*Data.jsone partes (PaginasData.part-001.json, 80 MB),db/data/schema-metadata.json,db/.c2f-migrations-projeto.json. Nenhum é editado à mão: são saídas do build ou da sincronização. -
config.phpdo core preservado como "editado" em três releases seguidas (3.0.9, 3.0.10, 3.0.11). O Lab ficou com$_GESTOR['versao'] = '3.0.8'(selo errado no dashboard) e sem a bibliotecaapi-crudregistrada (a API CRUD da REQ-283 não carregava). A única diferença além disso era CRLF, de uma sincronização a partir do Windows. -
Divergência escondida para sempre (
instalacao_planejar, regra da req-199): "a camada entrega o mesmo conteúdo da entrega anterior e o disco é outro → nada a decidir". A regra supõe que a divergência já foi decidida. Quando o disco mudou por fora (sync de teste, edição manual) e nunca houve choque, o arquivo fica velho em silêncio: 316 arquivos do projeto no Lab, sem nenhum choque visível. -
Sem decisão em lote. A tela de choques decide um por vez.
-
Diff com emoji não grava em
atualizacoes_choques.diffno MariaDB do Lab (Incorrect string value: '\xF0\x9F...'): a coluna não está emutf8mb4. O choque some da tabela. -
CRLF conta como edição. Arquivo igual a menos da quebra de linha vira "editado".
3. Escopo proposto
-
Lista de artefatos de sistema, sempre escritos pela camada dona (como
INSTALACAO_CORE_SEMPRE_ESCREVER, req-278), com a cópia anterior no snapshot:vendor/**,*.min.js,*.precompiled.css,assets/asset-versions.json,assets/modulos/covers/manifest.json,db/data/**(dados que a sincronização leva ao banco, onde já existe a proteção poruser_modified),db/.c2f-migrations-*.json. Vale para core e projeto; sobreposição por camada superior continua respeitada. A lista fica num só lugar e tem teste. -
config.phpdo core entra na lista do item 1 ou ganha tratamento próprio (o que é da instalação está no.env). Decidir com o Arquiteto. -
Divergência nunca escondida: a regra da req-199 só pula quando há decisão registrada para aquele disco (regra
manter, ou registro de mescla/sobrescrita com o hash do disco). Sem decisão, vira choque — e o filtro de pendentes iguais já impede duplicar. -
Decisão em lote na tela: por entrega (
versao+origem) e por pasta, com a mesma confirmação explícita do operador (DEC-136). Inclui "sobrescrever todos desta entrega" e "manter todos". -
atualizacoes_choques.diffemutf8mb4(migration) e falha de INSERT do choque registrada no log da execução. -
Comparação sem diferença de quebra de linha para arquivos de texto (normalizar
\r\nsó na comparação, não no arquivo). -
Arquivos de controle do servidor fora do manifesto:
db/.c2f-migrations-<dono>.json(req-194) é escrito pelo servidor e entrou no manifesto do projeto; virou 3 choques de retirada pendentes no Lab. Excluir deinstalacao_mapa/manifesto comoINSTALACAO_PASTAS_FORA. -
Tela de choques mais clara: a lista mostra os 50 mais recentes misturando pendentes e resolvidos, enquanto a aba conta só os pendentes (12 × lista maior, no Lab). Abrir com filtro "pendentes" e opção de ver resolvidos. Choque de retirada não tem versão nova nem diff: dizer isso na tela, em vez de mostrar o conteúdo vazio (o Engenheiro Chefe leu como "arquivo zerado"). Paginação como nas listas dos módulos (ex.:
admin-paginas, que usainterface_listar_tabela()/interface_listar_ajax()degestor/bibliotecas/interface.php), no lugar doLIMIT 50fixo: no Lab, 8 dos 12 pendentes ficavam fora da janela e não apareciam. -
Saneamento de instalação: comando/ação para o operador reconciliar uma instalação poluída por sincronizações de teste (o que foi feito à mão no Lab na REQ-285: resolver superados, aceitar a versão entregue, recalcular o manifesto).
4. Parecer do executor (REQ-285)
-
Concordo em tirar os artefatos gerados do choque — mas pela lista explícita do item 1, não por "ignorar pastas inteiras".
modulos/,bibliotecas/,controladores/,resources/econtents/têm código e conteúdo que alguém pode, sim, mudar no servidor; ali o choque protege. -
vendor/inteiro é seguro: só o Composer escreve ali, e a entrega traz o conjunto completo e coerente. Choque emvendor/só atrapalha (um arquivo velho no meio do vendor quebra o autoload). -
db/data/é o caso mais importante: foi ele que levou à retirada em massa da REQ-285. O dado que a pessoa edita mora no banco, protegido poruser_modified; o arquivo é só transporte. -
O item 3 é o mais grave dos que sobraram: hoje ele esconde exatamente o tipo de divergência que o choque existe para mostrar.
5. Critérios de aceite
-
Atualizar uma instalação com
vendor/,*.precompiled.cssedb/data/divergentes não gera choque desses arquivos; o snapshot guarda a versão anterior. -
Arquivo de código mudado no servidor continua virando choque.
-
Disco que diverge do manifesto sem decisão gera choque na entrega seguinte, mesmo com o conteúdo entregue igual ao anterior.
-
Operador decide todos os choques de uma entrega com uma ação, com confirmação.
-
Choque com emoji no diff é gravado.
-
Testes do atualizador e suíte do core verdes.