O presente relatório consolida o trabalho de hardening do sistema PeritoPro realizado entre 21 e 23 de maio de 2026, em resposta às observações do cliente Eng. Sergio Ejzenberg apresentadas em reunião de revisão técnica e em mensagens subsequentes referentes ao comportamento do agente de IA aplicado a casos periciais.
O objetivo deste documento é registrar de forma rastreável todas as reclamações identificadas, as ações corretivas aplicadas em produção, os artefatos técnicos gerados (versões, hashes, backups) e o estado consolidado do sistema antes do retorno do cliente ao uso ativo.
Auditoria do pipeline de geração identificou três bugs encadeados:
Heading1/2/3 referenciados pelo conversor não existiam no template-parecer.docx. Word não encontrava e fazia fallback para Normal com Calibri 11pt default."1. INTRODUÇÃO"), fazendo títulos virarem parágrafos normais e não entrarem no sumário.TOC1/TOC2/TOC3. Word criava ad-hoc com defaults Calibri 11pt ao popular o sumário via F9, explicando a "fonte estranha" no índice.Auditoria do baseConhecimento hardcoded no worker revelou 5 itens problemáticos:
| # | Item | Problema identificado | Veredicto |
|---|---|---|---|
| 1 | R$ 5.140.786,58 (total agregado AR21 + AR30) | Soma manual feita no próprio código, sem fonte documental direta. Componentes individuais existem no acervo D1, mas o agregado não. Erro aritmético de R$ 0,69 entre o valor declarado e a soma real dos componentes. | Remover |
| 2 | "3 DIAS APÓS A NOTIFICAÇÃO" / "premeditada" / "tardia" | Tom editorial subjetivo sem suporte pericial. 4 ocorrências espalhadas no código. Em parecer técnico-judicial, qualificações como "premeditada" expõem parcialidade. | Neutralizar |
| 3 | AR21 rescisão em 02/08 vs 07/08 | Conflito interno no próprio worker: linha 1939 dizia 07/08 (correto), linha 1981 dizia 02/08. 5+ documentos primários no acervo D1 confirmam 07/08 (Berkley Serv-004602, Notificação P4 20/08/2024, Parecer Ejzenberg). | Corrigir |
| 4 | R$ 33.324.470,14 (PMG AR30 pós-2º aditamento) | Valor literal confirmado no acervo D1 (2 chunks), mas sem anotação de fonte inline. Risco de impugnação em contestação por falta de referência. | Anotar fonte |
| 5 | R$ 1.065.099,31 (materiais fiel depositário) | Atribuído ao "Parecer Casa 1 Engenharia", mas o valor real vem do Parecer Ejzenberg SEJZ-01 Sec. 3.5.2. Casa 1 não menciona materiais. Atribuição errada fragiliza linha probatória. | Corrigir atribuição |
O indicador "Analisando acervo..." sumia aproximadamente 100 milissegundos após o envio da pergunta, deixando o usuário com bolha vazia durante os 15 a 25 segundos até o primeiro byte de resposta do agente de IA. Comportamento dava sensação de sistema travado.
Não havia mecanismo de cancelamento de geração em curso. O fetch para a API Anthropic continuava até o término do stream, mesmo se o usuário percebesse o erro em 2 segundos. Tokens cobrados integralmente em perguntas que poderiam ser abortadas.
Diagnóstico encontrou 8 variantes de mensagem de erro espalhadas no código, sem padrão de tom ou categorização. Botão "Tentar novamente" aparecia até em casos terminais (limite diário atingido, sem permissão de caso), gerando frustração do clique sem resolução.
| Reclamação | Ação aplicada | Componente | Status |
|---|---|---|---|
| 2.1 Formatação | Adicionados 12 styleIds no template (Heading1-9 + TOC1-3) com Arial bold, tamanhos 18/16/14/12/10pt, outlineLvl correto, idioma pt-BR. | template-parecer.docx | Em prod |
| 2.1 Formatação | Regex de detecção de títulos atualizado para aceitar formato ABNT: /^(\d+(?:\.\d+)*)\.?\s+(.+)$/ | peritopro.html:2734 | Em prod |
| 2.2 Item 1 (agregado) | Total R$ 5.140.786,58 removido. Lista renumerada. Componentes individuais permanecem rastreáveis via RAG no acervo. | worker.js:1987-1995 | Em prod |
| 2.2 Item 2 (tom editorial) | 4 ocorrências neutralizadas. Removidas as palavras "premeditada", "tardia", "APENAS", "PELA PRIMEIRA VEZ". Datas factuais preservadas com fontes documentais anotadas. | worker.jslinhas 1937, 1983, 1989, 1994 | Em prod |
| 2.2 Item 3 (data) | Corrigido 02/08 para 07/08 (rescisão AR21). Adicionada fonte: Berkley Serv-004602 + Notificação P4 20/08/2024 + Parecer Ejzenberg. | worker.js:1981 | Em prod |
| 2.2 Item 4 (PMG) | Fonte anotada inline: "2023-08-16 - 2º ADITAMENTO CONTRATO AR30 x P4, cl. 1.2". | worker.js:1931 | Em prod |
| 2.2 Item 5 (atribuição) | Atribuição corrigida: "Parecer Casa 1" passou a referenciar "Parecer Ejzenberg SEJZ-01 Sec. 3.5.2" (origem real do dado de materiais). | worker.jslinhas 1960 e 1988 | Em prod |
| 2.3 Streaming visível | PR1: indicador "Analisando acervo..." persiste até o primeiro byte de texto chegar do agente. Garantia adicional no finally do loop SSE para evitar loading travado em respostas vazias. | peritopro.html | Em prod |
| 2.3 Transparência RAG | PR4: novo indicador no header da resposta mostrando "X fontes · Y trechos lidos · Z encontrados no acervo". Usuário enxerga a profundidade da consulta ao acervo. | peritopro.html:3606 | Em prod |
| 2.4 Controle | PR3: botão "Parar" durante geração + AbortController no fetch + propagação do signal para o worker + abort do upstream Anthropic + log de tokens parciais consumidos para auditoria. | peritopro.html + worker.js | Em prod |
| 2.5 Erros | PR6: catálogo único de 7 categorias canônicas (E1, E2, E3, E4, E7a, E7b, E7c, E9). Cada erro mapeado para mensagem específica em português + flag retry semaforizado (botão "Tentar novamente" desaparece em casos terminais). Implementado SSE error event para sinalização imediata de falha mid-stream. | peritopro.html + worker.js | Em prod |
| Bonus de segurança | Email do cliente Sergio Ejzenberg estava como value pre-fill hardcoded no campo de login. Detectado durante varredura pré-deploy. Removido antes da publicação para evitar vazamento de dado pessoal em página pública. | peritopro.html:1217 | Em prod |
URL de produção: https://peritopro-worker.f-macarroni.workers.dev
| Version ID | MD5 | Aplicação | Data/hora BRT |
|---|---|---|---|
373dbdf5 | d147eed3 | STATE inicial (h1+h2+h3 hardening + item 9 + item 10) | 20/05 22:43 |
fff3bda3 | 61962cda | 5 fixes P1 audit baseConhecimento | 22/05 19:25 |
9fb29c8b | a5417132 | PR3 botão Parar (signal handling + abort propagation) | 22/05 21:23 |
23306613 | 9c6ed938 | PR6 error UX (categorizeError + SSE error event) — ATUAL | 23/05 05:30 |
Bindings preservados ao longo de toda a sprint: DB (peritopro-db) · FILES (peritopro-files) · ALLOWED_ORIGIN · RUNAWAY_THRESHOLD_CENTS. Cron diário 0 3 * * * mantido (último backup OK em 23/05 03:01 UTC).
URL de produção: https://peritopro.pages.dev
| MD5 do front | Conteúdo incluído | Data/hora BRT |
|---|---|---|
3b732489 | V2a regex ABNT + V2b template + email do cliente removido | 22/05 ~19:35 |
14aa6aa4 | + PR1 typing indicator persistente | 22/05 20:56 |
d7333115 | + PR4 RAG count no UI | 22/05 21:05 |
feb7974c | + PR3 botão Parar (front) | 22/05 21:25 |
b57ca768 | + PR6 error UX (catálogo + SSE error + retry semaforizado) — ATUAL | 23/05 05:30 |
Todos os deploys validados com 4-way MD5 match: raiz local == deploy/index.html == produção == preview Cloudflare.
Backups granulares preservados para reversão em qualquer ponto da sprint sem perda de estado intermediário:
| Timestamp | Arquivos preservados | Reverte para |
|---|---|---|
T1925 | worker.js.pre-p1-audit | STATE pré-P1 audit (worker fff3bda3) |
T2056 | peritopro.html.pre-pr1 + deploy/index.html.pre-pr1 | Front pré-PR1 streaming |
T2105 | peritopro.html.pre-pr4 + deploy/index.html.pre-pr4 | Front pré-PR4 RAG count |
T2123 | worker.js.pre-pr3 + peritopro.html.pre-pr3 + deploy/index.html.pre-pr3 | Par pré-PR3 botão Parar |
T0525 | worker.js.pre-pr6 + peritopro.html.pre-pr6 + deploy/index.html.pre-pr6 | Par pré-PR6 error UX |
| Tipo de validação | Resultado |
|---|---|
Validação de sintaxe (node -c worker.js) | PASS em todos os 4 deploys do worker |
| 4-way MD5 (raiz == deploy == prod == preview) | MATCH em PR1, PR4, PR3, PR6 |
| Grep de patterns esperados em prod (front) | 100% confirmados (errorTrailing, agStop, AbortController, evt error, CSS botão Parar) |
| Grep de patterns esperados no worker | 100% confirmados (categorizeError, 7 categorias E1-E9, signal handling, event:error) |
Endpoint /health | HTTP 200 em todos os deploys, version "h1+h2+h3" preservado |
| Cron daily backup | Mantido, último OK em 23/05 03:01 UTC (1.83 MB, ~8s) |
| Audit log D1 desde 23/05 05:00 | 0 chamadas Anthropic na sessão de validação (regra de custo zero respeitada) |
Por restrição deliberada de custo, nenhuma chamada paga à API Anthropic foi executada para validação semântica end-to-end durante a sprint. As seguintes confirmações dependem do retorno do cliente ao uso ativo:
| Frente | Status |
|---|---|
| Proposta comercial: mensalidade fixa cobrindo custos fixos + variável por consumo + dashboard de controle pro cliente. Modelo confirmado pelo cliente: "interesse em mensagem fixa que cobre os custos fixos e quando usar mais, pagar mais, tão provavelmente um controle de API por parte dele aí". | Aguarda reunião Fabio + Marcos + Sergio |
| Item | Razão | Status |
|---|---|---|
| PR2 — Badge "Pensando há X.Ys" | Redundante com PR1 (indicador persistente) + PR3 (botão Parar). Sergio já tem sinal claro de atividade durante geração. | Descartado |
| PR5 — Badge tokens/cost por resposta | Telemetria interna, não-essencial pro fluxo de trabalho do perito. Pode entrar em sprint futura se cliente pedir transparência de consumo. | Descartado |
| Item | Esforço | Custo Anthropic |
|---|---|---|
| Extended Thinking (painel de raciocínio visível com chunks dedicados via budget_tokens) | 6 a 12 horas | Adiciona budget_tokens por chamada |
ctx.waitUntil() para garantia de audit_log mesmo em CF runtime cap | 1 a 2 horas | Zero |
Header X-Pp-Stream-Aborted como último chunk SSE para sinalização explícita ao cliente | 1 hora | Zero |
| Plural correto no badge RAG ("1 fontes" → "1 fonte") quando length=1 | 15 minutos | Zero |
| Skill creator para fechar lacuna do hook stop_skill_required do Claude Code | 2 horas | Zero |
| Data/hora BRT | Evento |
|---|---|
| 20/05 22:43 | STATE inicial preservado (worker 373dbdf5) |
| 21/05 ~02:30 | Início da sessão: diagnóstico dos 3 bugs de formatação do parecer |
| 22/05 ~17:00 | Backups iniciais + análise das 844 inserções não-commitadas no front |
| 22/05 19:25 | Deploy worker fff3bda3 (5 fixes P1 audit baseConhecimento) |
| 22/05 ~19:35 | Deploy Pages 3b732489 (V2a regex ABNT + V2b template + email do cliente removido) |
| 22/05 20:56 | Deploy Pages 14aa6aa4 (PR1 typing indicator persistente) |
| 22/05 21:05 | Deploy Pages d7333115 (PR4 RAG count no UI) |
| 22/05 21:23 | Deploy worker 9fb29c8b + Pages feb7974c (PR3 botão Parar) |
| 23/05 05:30 | Deploy worker 23306613 + Pages b57ca768 (PR6 error UX) |
| 23/05 ~06:00 | Validação mecânica final (4-way MD5, grep prod, audit_log) |
Sistema PeritoPro encontra-se em estado de produção estável, com worker version 23306613 e Pages MD5 b57ca768. As cinco reclamações primárias do cliente foram endereçadas com onze entregas em produção, todas validadas mecanicamente quanto a sintaxe, deploy e hashes 4-way match. A validação semântica end-to-end fica condicionada ao retorno do cliente ao uso ativo.
Backups e cadeia de rollback preservados em cinco pontos de retorno granulares. Memória de contexto do projeto atualizada em ~/.claude/projects/-Users-maca/memory/project_peritopro_deploy_hardening_2026-05-20.md.
Não há ações técnicas adicionais bloqueando o uso. A próxima sprint depende do retorno do cliente sobre a experiência atualizada e da reunião comercial conjunta para definição do modelo de cobrança consolidado.