Contexto
A v0.5.0 identificou a cor #333 do rodapé do template como gatilho do 403-WAF e destravou a edição. Um dia depois o mesmo documento voltou a ficar inescrevível — inclusive reenviando o conteúdo exatamente como estava gravado, sem alterar nada. O diagnóstico anterior estava certo no mecanismo e incompleto no alcance.
O que mudou no diagnóstico
O gatilho é qualquer cor hexadecimal em atributo style, não o #333 do rodapé em particular. Desta vez foram dois color:#000000 no corpo do documento. Como o padrão vem tanto do template do SEI quanto de conteúdo colado (Word cola hex o tempo todo), não é um documento com defeito — é uma classe inteira de documentos.
Duas hipóteses foram testadas e descartadas antes de chegar lá:
Não é reputação de origem. Havia a suspeita de que requisições saindo de datacenter nos EUA (IAD) fossem pontuadas pior que as de origem brasileira (GIG). O bloqueio foi reproduzido do Brasil com o mesmo corpo — a diferença não estava no caminho.
Não é score puramente acumulativo. Removendo janelas de mesmo tamanho em offsets diferentes, apenas 2 de 10 remoções faziam o corpo passar, e ambas continham as cores hex. Se fosse limiar de massa, qualquer corte equivalente resolveria.
Uma correção de método que vale registrar
A bissecção por prefixo usada na v0.5.0 produz fronteiras artificiais. Ela corta no meio de tags e palavras: num dos casos o limite "exato" caiu entre oportunam e oportuname, o que não é fronteira de padrão nenhum — é artefato de truncamento.
A substituição é remoção por janelas de mesmo tamanho em offsets diferentes, que separa o que a bissecção confunde: poucas remoções fazendo passar indica culpado local; quase todas passando indica score acumulativo. Junto com isso, passou a valer verificar determinismo (repetir o payload idêntico três vezes) antes de concluir qualquer coisa — sem isso, flutuação de pontuação vira "padrão descoberto".
Degrau novo: cores hexadecimais → rgb()
No 403-WAF, a tool reescreve as cores hex como rgb() equivalente e refaz o POST. A troca é neutra na renderização, então o documento não muda aos olhos de quem o lê.
A reescrita é restrita ao valor de atributos style, de propósito: um regex solto casaria entidades numéricas como é e corromperia o texto do documento. Há teste cobrindo exatamente isso.
Correção de regressão: validação de âncora
A checagem validar_referencias perguntava se o número da âncora era protocoloFormatado de algum documento e, em caso afirmativo, declarava a âncora errada. A regra real do core é outra — EditorRN::processarLinkProtocolo exige que o texto do link seja o protocoloFormatado do id, e descarta a tag quando não são iguais. E idProtocolo abrange processos, não só documentos.
Resultado: a âncora <a id="lnkSei2378553">50300.004460/2024-86</a> estava correta o tempo todo — 2378553 é o id do processo. O aviso era falso positivo por colisão de namespace (2378553 também existe como nº SEI de um documento), e agir sobre ele fez o SEI descartar a tag e o link desaparecer do documento.
A checagem agora parte do texto do link, que é o que o usuário vê, e se cala diante de âncora de processo. Teste de regressão cobrindo o caso.
Validação
Na Nota Técnica 105 (SEI 2979052): v15 gravada exercitando o degrau hex→rgb() ao vivo — tentativa 1 barrada pelo WAF, tentativa 2 gravou; e v16 com a âncora restaurada, que sobreviveu ao salvamento, provando que era válida desde o início. Documento íntegro: 9 títulos, 6 âncoras SEI, 4 links externos, brasão e rodapé regenerados. 73/73 testes passando.
O conserto durável continua sendo do lado da infraestrutura
Trocar #333 no modelo do SEI, sugerido na v0.5.0, resolve um sintoma. Com o gatilho agora entendido como "qualquer hex em style", fica claro que não escala: milhares de documentos carregam cor hexadecimal colada de editor externo, e cada um vira um documento que a API não consegue salvar.
A exceção de WAF em /sei/modulos/wssei/, restrita por IP de origem conhecido, é o que fecha a classe inteira.