# Restrição comercial opcional — núcleo

A organização pode exigir atendimento exclusivamente humano para preços, negociação e condições de pagamento. O interruptor fica na tela do agente, aba Segurança (`PainelDeSeguranca`, via `/api/v1/ai/guardrail-layers`), e vale para a organização inteira: é a camada `restricao_comercial` de `org_guardrail_layers` (vocabulário aberto, sem migration). Default desligado: outras organizações continuam operando. Não é tabela de preços nem validação de veracidade — as conferências `promise` e `semantic_promise` **validam** o valor que a IA cita; esta **proíbe** a IA de falar de valor.

Consumidores: `escalarComercialAntesDoModelo` no handler do inbound, antes de `resolveConversationTurn` (automático e assistido); a prévia faz a mesma triagem dentro do turno e só propõe; `commercialRestrictionGate` na cadeia v10; a prévia usa a mesma camada. Identificação por termos/padrões conservadores PT/es, não classificador universal. Número sozinho não conta como preço (data e hora com ponto, "2x ao dia", "40%"): só com moeda, parcela ("em 3x", "10x de"), "% off" ou vírgula com duas casas. A régua de SAÍDA (`contemAssuntoComercialNaSaida`, a do gate) é mais estrita, porque só barra envio: soma moeda sem número colado (R$, BRL, USD, EUR), "valor" e "à vista" soltos, palavras de preço em espanhol e inglês, moeda por extenso, decimal com ponto em posição de preço ("por 299.90", "299.90 cada"), honorários/abatimento/cupom/pesos, parcela com o valor depois ("10 vezes de 29", "3x 600", "12x150"; com espaço e sem "de", "10 vezes 99" e "12x 50" também barram, desde que o número tenha dois dígitos e não venha seguido de unidade ou frequência — "2x 30 minutos", "3 vezes 10 repetições"; colado ao "x", o valor precisa de três dígitos ou centavos, então "foto 3x4" e "3x12 repetições" passam) — "N vezes" sozinho é frequência ("remarcou 3 vezes", "use 2 vezes diariamente") e não barra e inteiro ou milhar depois de verbo de preço ("faço 1800", "por 1.800", menos ano e "mais de 1.000"); data e hora com ponto continuam fora. A entrada também reconhece investimento, mensalidade, anuidade, "sem juros" e "em 10 vezes". Não reconhece toda paráfrase, mídia ou cifra oblíqua; há falsos positivos possíveis. Endereço, telefone e horários habituais medidos permanecem permitidos. Outras restrições continuam independentes.

**Leitura que falha não libera.** `comercialExigeHumano` lê a camada à parte de `lerCamadasDaOrg` (que falha aberta) e lança quando a consulta estoura: o turno cai e o job volta para a fila, em vez de a IA responder sobre preço.

**A cadeia não depende de quem chama lembrar.** `runBeforeSend` sem `enforceCommercialRestriction` lê a camada ele mesmo quando o corpo tem cara de preço, e a leitura que falha conta como ligada. Assim o template que o modelo escolhe, a pergunta do roteiro e o texto fixo do follow-up também são barrados. O texto fixo tem um segundo consumidor fora da cadeia — o atalho inline `enviarTextoFixoPendente` (cron `followup-flow-worker`, `aplicar-inbound`, relógio) —, que aplica a mesma régua (`restricaoComercialBarra`, falha fechada) e fecha o passo como o veto da cadeia fecha: `skipped`, job concluído, sem re-agendar. Dos envios que passam pela cadeia, ficam fora só resposta aprovada por humano (`approvedReply`), o link do Meet (`meetingDelivery`) e o aviso de escalação, que passa `false` explícito por ser texto fixo do sistema.

**STOP e pedido de humano vêm antes.** Se o que o cliente ainda não teve resposta casa com opt-out provável (`lib/opt-out/deteccao.ts`, via `detectAmbiguousOptOut`) ou com pedido explícito de humano, a passagem comercial não age: o turno segue para as detecções determinísticas, que registram a parada ou a passagem. Contato bloqueado não recebe o aviso comercial (o `stopGate` lê `is_blocked` na fonte).

Entrada detectada real avisa o cliente (`avisarLeadLendoOContato`, antes de o contexto do turno ser lido) e depois chama `performHumanHandoff` com o desfecho do aviso: briefing, silêncio infinity, cancelamento de crons e demanda no Inbox. Prévia propõe a passagem sem executar nem transmitir. Saída comercial barrada não chama transporte, grava trace, avisa o cliente (`avisarLeadDaEscalacao`, com o contexto do turno) e encaminha à equipe; não libera preço após insistência. Não confirma prazo/atendente existente. Filas por unidade ainda exigem implementação própria; a demanda vai para carteira/fila humana nativa.

**A "Mensagem escrita pela IA" passa pela mesma régua desde o #3359.** A ação de automação `send_ai_message` gera o texto por IA e envia por `sendMessageHandler`, fora da cadeia; antes do envio ela aplica `restricaoComercialBarra` (com `comercialExigeHumanoViaSupabase`, falha fechada). Quando barra, a mensagem não sai, a conversa é passada para a equipe por `triggerHandoff`, com o mesmo motivo e o mesmo texto da cadeia, e o run fecha `skipped` com `commercial_requires_human` (frase própria na aba Atividade dos webhooks) — ou com `commercial_requires_human_sem_passagem` quando o orquestrador recusa a passagem, para a tela não afirmar um handoff que não houve.

Living System Checklist: entrada (mensagens/configuração), saída (handoff/before_send), log (trace/handoff_triggered), tela (Segurança do agente/Testar/Inbox), porta (IA › Agentes › agente › Segurança), próximo passo (fila humana), configuração (interruptor + PUT admin em guardrail-layers, auditado como `ai.guardrail_layer_changed`), continuidade (handoff e retorno humano nativos), feedback (revisão manual dos falsos positivos, sem aprendizado automático), mapa (`atendimento-comercial.architecture.json`).

Fora desta entrega: a ação de automação `send_whatsapp_message`, as campanhas, a prospecção (`lib/prospecting/worker.ts`, que gera o texto por IA e envia por `sendMessageHandler`) e o envio por MCP externo (`lib/mcp/tools/messages.ts` e `lib/mcp/tools/start-conversation.ts`) não passam por `runBeforeSend` e não herdam a restrição; permanecem desativadas até homologação. A palavra-chave de handoff configurada no agente não vence a passagem comercial (ela é decidida antes de o agente ser escolhido); o desfecho é passagem para a equipe do mesmo jeito. Regra de opt-out continua nativa; não altera consentimentos. Não é garantia de zero alucinação. Testes pareados do mesmo texto na cadeia e na prévia, transporte não chamado. Sem dados reais de clientes.
