


Altere um proxy reverso em Rust sem quebrar o loop de eventos nem a segurança
Use quando uma IA alterar, testar ou lançar um proxy Rust multiprocessos. Define regras para build e feature flags, erros e registros, loop de eventos e protocolo, testes e fuzzing, código sensível à segurança, pull requests e lançamento.
Para usar estas regras de IA
## Respeite as camadas de bibliotecas do proxy e a direção das dependências
Trate o repositório como um sistema em camadas com uma direção de dependência explícita:
- Uma biblioteca do plano de controle é responsável pela análise da configuração, pelos esquemas de comandos, pelo estado compartilhado, pelos auxiliares de registro e pelos canais entre processos.
- Uma biblioteca de protocolo e runtime é responsável pelo loop de eventos em uma única thread, pelo roteamento, pelos sockets, pelos buffers, pelas métricas, por TLS, HTTP e pelo tratamento do protocolo de proxy.
- Um crate binário é responsável pelo supervisor, pelos processos de trabalho, pela CLI, pelo carregamento da configuração, pela reconfiguração a quente, pelas atualizações e pelo servidor de comandos.
- Os crates de testes de integração e de simulação determinística dependem das bibliotecas de runtime, mas não devem deixar suas dependências assíncronas ou exclusivas de testes vazarem para o código de produção.
- Os alvos de fuzzing podem ficar fora do workspace principal quando seus requisitos de cadeia de ferramentas forem diferentes.
Preserve a direção das dependências do código de runtime para o código do plano de controle. Mantenha cada processo de trabalho em uma única thread, evite mutexes compartilhados no loop de eventos e mantenha as bibliotecas de produção livres de runtimes assíncronos, a menos que a arquitetura seja deliberadamente redesenhada.
## Compile com a toolchain fixada e teste as combinações de funcionalidades
Antes de alterar o código, identifique a cadeia de ferramentas Rust fixada e os geradores de código necessários. Se a geração de esquemas for um pré-requisito obrigatório, instale ou verifique o gerador antes de interpretar falhas de compilação.
Use dependências bloqueadas nas compilações e nos testes normais. Execute o formatador com a cadeia de ferramentas exigida pela configuração do repositório, execute a análise estática negando avisos e teste todo o workspace antes de trabalhos voltados ao lançamento. Use conjuntos de testes específicos durante a iteração e depois retorne aos controles no nível do workspace afetado.
Trate os sinalizadores de funcionalidades como células explícitas de compatibilidade:
- Mantenha documentadas as escolhas padrão de alocador e criptografia.
- Teste separadamente cada provedor de criptografia compatível, inclusive os modos voltados à conformidade.
- Nunca habilite ganchos de injeção de testes em compilações de produção.
- Mantenha como opções de adesão o registro de depuração ou rastreamento, a tolerância do analisador, SIMD, a E/S sem cópia e os recursos de telemetria quando eles alterarem o comportamento, o tamanho ou a observabilidade.
Não declare uma alteração limpa apenas porque uma compilação padrão passou. Confirme as combinações de funcionalidades diretamente afetadas pela alteração.
## Trate erros e registros sem panic e não edite à mão o código gerado
Use erros estruturados nas bibliotecas e acrescente contexto amplo apenas nos limites dos executáveis. Uma entrada controlada pela rede deve se transformar em erro de protocolo, ação de conexão, métrica e registro contextual; ela nunca deve acionar `unwrap`, `expect`, `panic` nem um ramo inalcançável no caminho de lançamento.
Siga as convenções de propriedade do código próximo. Prefira conversões que revelem a intenção ao transformar strings ou bytes emprestados em valores com propriedade, e use clonagem comum quando o tipo já for um valor clonável com propriedade.
Os módulos de protocolo devem usar suas macros estabelecidas de registro contextual e etiquetas de busca estáveis. Preserve o envelope canônico de sessão, solicitação e backend para que os operadores possam correlacionar falhas. Use os níveis de depuração ou rastreamento para fechamentos ociosos esperados e estados ruidosos; reserve os níveis de aviso e erro para falhas reais de protocolo ou violações de invariantes.
Mantenha as métricas públicas na camada central de métricas e atualize a referência de configuração voltada aos usuários ao acrescentar ou renomear uma delas. Trate o estouro inferior de um medidor como erro de correção.
Nunca edite manualmente as vinculações de protocolo geradas. Edite o esquema de origem e gere-as novamente por meio da compilação. Código inseguro novo em um caminho crítico exige uma explicação próxima da invariante e um teste específico.
## Evite que gravações em socket e buffers travem o loop de eventos
Para E/S acionada por borda, não basta enfileirar bytes a partir de um caminho de leitura: sinalize explicitamente a prontidão de escrita pendente. A ausência desse sinal cria sessões que travam apenas em limites específicos de quadro ou buffer.
Mantenha estruturalmente simétricas as implementações de escrita escalar e vetorizada em sockets, inclusive o comportamento de repetição e de escrita parcial. Em frontends criptografados, evite um encerramento duplex completo que possa emitir uma redefinição e truncar bytes já enfileirados; feche o lado de escrita e permita que o fechamento pelo par siga o caminho normal de leitura.
Mantenha um buffer grande o suficiente para o quadro máximo do protocolo mais o cabeçalho. Valide essa configuração na inicialização, em vez de permitir que um buffer pequeno cause um impasse no código de enquadramento.
Mantenha o estado de conexão no nível do fio separado do estado de fluxo que possui o buffer e faça referências cruzadas entre eles por meio de identificadores estáveis com regras verificadas de ciclo de vida. A negociação de protocolo do frontend e as indicações de capacidade do backend são conceitos diferentes; não use um deles como controle acidental do outro.
Os controles de inundação devem cobrir tempestades de redefinições, cadeias de continuação, quadros de controle repetidos e abuso de prioridade. A reconfiguração multiprocessos a quente deve validar os comandos no supervisor antes de distribuí-los aos processos de trabalho de thread única.
## Teste em camadas com fuzzing e simulações reproduzíveis
Use cinco camadas de teste complementares: testes unitários junto aos módulos, testes de integração no nível do processo, alvos de fuzzing, simulação determinística para máquinas de estado sem E/S e proteções contra regressões de contratos estruturais, como a disposição dos registros.
Para analisadores e funções não triviais de máquinas de estado, codifique pré-condições, pós-condições e asserções positivas e negativas nas compilações de depuração. Os pontos de entrada públicos das máquinas de estado devem terminar com uma verificação completa das invariantes. As asserções descrevem impossibilidades internas; uma entrada de rede adversária ainda deve retornar um resultado de protocolo seguro.
Conduza simulações determinísticas com uma fonte aleatória que use uma semente, tempo virtual, cargas adversárias e injeção de falhas. Registre as sementes para que toda falha possa ser reproduzida. Restrinja ao crate de simulação os sinalizadores de runtime e as dependências exclusivos da simulação.
Os testes de integração devem alocar portas dinamicamente, ler respostas TCP completas em vez de um único segmento e usar prazos explícitos ou condições de repetição até o êxito, em vez de pausas arbitrárias. Um teste ignorado precisa de uma dependência concreta do ambiente ou de um motivo rastreado; nunca use a omissão para ocultar uma regressão.
Para alterações de atualização, análise, compressão ou enquadramento, execute o conjunto específico de testes de integração e os alvos de fuzzing correspondentes, além dos testes gerais.
## Altere TLS, parsers e framing com cuidado e com testes de regressão
Faça alterações conservadoras e respaldadas por testes na configuração de TLS, na negociação de protocolo, na vinculação de nomes, no carregamento de certificados, na normalização do analisador e dos cabeçalhos, no controle de fluxo, no enquadramento de comandos, na passagem de descritores, nas métricas e nos registros.
Rejeite o enquadramento ambíguo de mensagens em vez de encaminhar uma representação diferente do enquadramento realmente aplicado. Preserve a ordem dos pseudocabeçalhos, a conciliação do tamanho do conteúdo, as defesas contra contrabando de solicitações e a semântica correta de redefinição ou encerramento normal.
Nos canais de comandos, valide os prefixos de tamanho, as mensagens parciais, a transferência de descritores de arquivo, a reprodução de estado e os limites dos buffers. Para o tratamento do protocolo de proxy, cubra cabeçalhos parciais e grandes demais, além do tráfego de verificação de integridade.
Não exponha segredos nem valores confidenciais por meio de registros ou métricas. Mantenha contadores e medidores corretos em todos os caminhos de erro e encerramento.
Ao alterar o loop de eventos ou o código de segurança, acrescente cobertura de regressão específica para a invariante exata e depois execute os testes de protocolo adjacentes. Não misture refatorações sem relação na mesma alteração.
## Informe nos pull requests o impacto no protocolo e na segurança
Leia a nota canônica de ciclo de vida ou arquitetura antes de alterar um subsistema de protocolo complexo. Trate documentos antigos como indícios e confira as referências deles a arquivos com o código atual.
Use branches de escopo limitado e mensagens de commit convencionais que identifiquem o subsistema afetado. Siga a política de assinatura e confirmação do repositório. Quando uma tarefa autorizar a publicação, envie o branch com os commits e informe a execução de CI resultante; caso contrário, pare no limite autorizado localmente.
Baseie as alterações no branch padrão atual, a menos que um branch de integração ativo seja explicitamente indicado. As solicitações de integração devem descrever o impacto no protocolo ou na segurança, os comandos executados, os testes acrescentados e as alterações na documentação. Respeite os controles de propriedade e de licença dos colaboradores.
Atualize os registros de alterações e as referências de configuração quando um comportamento visível para usuários ou operadores mudar, inclusive chaves de configuração, métricas, sinalizadores de linha de comando e requisitos de atualização.
Antes da entrega, revise o diff em busca de arquivos gerados, vazamento acidental de funcionalidades, testes ausentes, referências obsoletas e edições sem relação.
## Lance só com aprovação e teste antes as atualizações a quente
Trate a implantação como uma etapa autorizada separadamente. Primeiro compile o artefato de lançamento com dependências bloqueadas ou congeladas; depois valide a configuração e execute os controles de prontidão afetados em um ambiente equivalente ao de homologação.
Os pacotes do contêiner e do sistema operacional devem instalar os mesmos pré-requisitos de compilação usados localmente, inclusive geradores de esquemas e bibliotecas da plataforma. Fixe a cadeia de ferramentas e mantenha as dependências exclusivas de testes fora dos artefatos de produção.
Para regressões do loop de eventos ou do ciclo de vida dos processos de trabalho, reproduza com um processo de trabalho, a reinicialização automática desabilitada e os rastreamentos de pilha habilitados. Isso mantém a primeira falha visível, em vez de permitir que a recuperação do supervisor a oculte.
As atualizações a quente devem preservar as invariantes de transferência de listeners e sessões. Teste explicitamente os caminhos de atualização antes do lançamento. Não trate uma reinicialização comum bem-sucedida como prova de que a transferência de descritores ou a reprodução funciona.
Não implante em produção, altere credenciais nem realize recuperação destrutiva sem autorização explícita e um caminho de reversão. Informe o que foi compilado, quais controles passaram, o que continua sem verificação e o limite exato em que o trabalho parou.
