CORTEX · doc

AI Wallet

IA de qualificação

13 regras · v0.2.2 · rascunho · owner: plataforma · 19 KB · ai-wallet-service · sumário em JSON

CORTEX — ai-wallet (IA de qualificação)

Versão: 0.2.2 · Data: 2026-09-24 · Status: Rascunho · Owner: Plataforma Caminho canônico: cortex-docs/services/AI_WALLET_SERVICE.md Documentos irmãos: cortex-docs/ECOSYSTEM.md (mapa do ecossistema) · cortex-docs/standards/UNISCALE_ENGINEERING_STANDARDS.md (padrões técnicos) · cortex-docs/services/INSTITUTIONAL_SERVICE.md (dono da config comercial)

Este documento define as regras do ai-wallet — a IA de qualificação do CORTEX. Rascunho pendente de revisão.

A ai-wallet é uma via opcional do funil (ECOSYSTEM §4): não está no caminho obrigatório da venda. Ela envia conteúdo gratuito e convida para comunidades; o lead consome esse material e pontua (ou perde pontos quando não consome no prazo); quem cruza o limiar fica qualificado e chega mais quente ao ai-sales. O ai-sales puxa esse contexto na fonte (resolve o ID no identity-service e lê direto da wallet), de bastidor — não escancara a oferta.

Tem banco próprio (UNISCALE — banco-por-serviço). Não tem banco vetorial: a conversa da IA sobre o material (RAG) hoje vive no protótipo (n8n) e está fora do banco deste serviço (ver Fronteiras). A wallet publica o que decide como fato (outbox), não serve contexto consolidado ao vivo (ECOSYSTEM §5).

Nota de nomenclatura (decisão de plataforma). Este serviço está sendo construído antes do Cortex, isolado, sob o repositório ai-wallet (ganho de tempo de desenvolvimento). O nome canônico correto pelo padrão UNISCALE §7 (<domain>-service) é wallet-ai-service — e o UNISCALE permanece com esse padrão. A renomeação (repositório, este doc, canonical_path e slugs ecosystem.services.ai-wallet-*) ocorre quando o serviço entrar no Cortex. Até lá, ai-wallet é apelido de desenvolvimento.


1. Papel e fronteira: IA de qualificação, via opcional (Obrigatório)

A ai-wallet qualifica, não vende e não matricula. É opcional: um lead pode fechar a venda sem nunca passar por ela. O que ela produz — conteúdo consumido, pontuação, estado de qualificação — é insumo de bastidor para o ai-sales, nunca um passo obrigatório do funil. A wallet não chama o ai-sales nem empurra o lead; ela mantém o estado e publica o fato quando o lead qualifica (§6). Quem decide agir sobre isso é o ai-sales, lendo na fonte (§7).

2. Catálogo próprio; byte no storage, referência local (Obrigatório)

O catálogo de conteúdo é da wallet (ela é dona do material de aquecimento). O byte não mora aqui: arquivo próprio vive no storage-service e a wallet guarda a referência (object_key) + metadado local; conteúdo externo (live, artigo, evento de comunidade) guarda um external_ref (link/identificador), sem object_key.

Todo item carrega, no mínimo: tipo, título, pontos (o que soma ao lead quando consumido — §4) e status (draft/published/archived). Carrega também, quando houver: descrição, resumo, tags, comunidades, validade, janela de envio (início/fim) e a referência de curso/produto-alvo — que é um ID distribuído pelo institutional-service (config), não um dado que a wallet inventa. O institutional não cadastra o conteúdo; ele só é a autoridade do ID de curso referenciado.

O conteúdo carrega ainda o prazo de consumo e a penalidade por não consumo, que variam por material (§9).

Vocabulário: o que o negócio chama de "pontos" do material é o campo técnico points do conteúdo. É a mesma informação — não confundir com o score do lead (§4), que é o acumulado.

3. A entrega nasce no envio; o consumo é o desfecho (Obrigatório)

A wallet registra o envio. A entrega de um conteúdo a um lead nasce quando o conteúdo é enviado — não quando é consumido. O consumo é o desfecho opcional dessa entrega.

Quem valida o consumo é o sistema que serve o conteúdo — a landing page, o repositório de vídeo, a plataforma da comunidade —, não a wallet. Esses sistemas decidem o que conta como acessou / leu / concluiu e reportam à wallet, que registra o consumo na entrega correspondente. A wallet não rastreia progresso parcial (% assistido).

  • O envio é único por (tenant, lead, conteúdo). Reenviar é repetir o mesmo link: não cria entrega nova — apenas registra o último envio. O reenvio não reinicia o prazo (que conta sempre do primeiro envio — §9) nem reabre a penalidade já aplicada.
  • "Não consumido" é ausência, nunca um tipo de consumo. Enquanto não há consumo, a entrega fica sem data e sem tipo de consumo. Não existe um valor de "tipo de consumo" significando "não consumiu" — isso criaria estado contraditório e duas fontes da verdade (o vencimento é marcado como na §9).

4. Pontuação: soma dos pontos, menos as penalidades, nunca negativa (Obrigatório)

Os pontos moram no próprio conteúdo (§2). A pontuação do lead é a soma dos pontos dos conteúdos que ele consumiu, menos as penalidades por não consumo no prazo (§9). Cada conteúdo distinto soma uma vez (garantido pela unicidade da entrega — §3).

O score nunca é negativo: penalidade que ultrapasse o saldo zera o score — não vira dívida.

O score é materializado no lead (para o ai-sales ler barato na fonte — §7), mas é cache: a verdade é o registro de entregas × pontos × penalidades, e o score é sempre recomputável a partir dele. Mudar os pontos de um conteúdo muda a política sem deploy (é dado do catálogo).

5. Estados do lead, qualificação e elegibilidade de mensagem (Obrigatório)

O lead tem um estado único (UNISCALE — estado em campo único), de vocabulário fechado:

engaging · inactive · qualified · student

A transição para qualified é disparada por limiar de pontuação: quando o score cruza o qualification_threshold do tenant, a wallet marca qualified, grava o instante e publica o fato (§6). O limiar é configuração por tenant, da própria wallet (a qualificação é regra da wallet), não distribuída pelo institutional.

Este estado é o ÚNICO critério de elegibilidade de mensagem: recebem material quem está em engaging ou qualified; inactive e student não recebem. Nenhum fluxo pode inventar outro critério nem outra palavra para a mesma situação.

inactive (esfriou por inatividade) depende de uma rotina de inatividade que ainda não está no escopo do v1 — o estado existe; a rotina que o aplica será escrita depois (ver Fronteiras).

6. Fato publicado: lead qualificado (Obrigatório)

Ao qualificar (§5), a wallet publica um fato — ai_wallet.lead.qualified — no exchange topic (ECOSYSTEM §5), pela outbox (mesma transação que muda o estado; UNISCALE — outbox). É o único fato publicado nesta fase (não há evento de "avanço de engajamento"). O payload carrega referência, não PII: tenant_id, identity_ref (ID opaco do identity), score, state, qualified_at e o trigger da transição — nunca nome, CPF, e-mail ou telefone (§12). A wallet não sabe quem ouve e não chama consumidor direto. A nomenclatura exata do evento segue a regra transversal uniscale.events.naming.

7. Contexto lido na fonte pelo ai-sales — resumido (Obrigatório)

Quando o ai-sales quer o contexto de um lead que passou pela wallet, ele resolve o ID no identity e lê direto da wallet (ECOSYSTEM §6 — contexto rico puxado na fonte, não consolidado para servir ao vivo). O que a wallet expõe é um contexto resumido: pontuação atual, estado, qualified_at e os últimos N conteúdos consumidos (título/tipo/data) — não o histórico completo. A wallet não empurra esse contexto; o ai-sales puxa quando precisa e usa de bastidor. O contrato exato dessa leitura (forma do resumo, N) é acordado com o ai-sales (ver Fronteiras).

8. Multi-tenant: tenant_id em toda tabela de negócio (Obrigatório)

A ai-wallet é multi-tenant (várias instituições do Hub). Aplica-se a regra transversal uniscale.columns.multi-tenancy (UNISCALE §23.3): tenant_id (uuid) em toda tabela multi-tenant desde o dia 1, e o modo de isolamento — coluna tenant_id (padrão) ou schema-por-tenant (cliente que exija sigilo) — é decidido lá, não aqui; mesmo em schema-por-tenant, tenant_id permanece na tabela. Nenhum vínculo cruza tenants: uma entrega só liga lead e conteúdo do mesmo tenant (garantido por FK composta por tenant_id). O tenant_id nasce fora da wallet: o dono é o institutional (registro de tenants distribuído por fato — ecosystem.services.institutional-tenant-registry). Enquanto a wallet roda antes do Cortex (apelido de dev), o valor é preenchido à mão; ao entrar, passa a consumir o fato.

9. Vencimento sem consumo e penalidade, aplicada uma única vez (Obrigatório)

Cada conteúdo define quanto tempo o lead tem para consumir e quantos pontos perde se não consumir — ambos variam por material (§2). Conteúdo sem prazo ou sem penalidade definidos não penaliza (ausência = não pune; nunca um prazo global implícito).

Uma rotina periódica varre as entregas que estão enviadas, não consumidas e ainda não vencidas. Para as que passaram do prazo — contado do primeiro envio, não do reenvio (§3) — ela, na mesma transação: marca a entrega como vencida e desconta a penalidade do score do lead (§4, com o piso em zero).

A marca de vencimento é o que garante a idempotência: uma entrega vencida é penalizada uma única vez, por mais vezes que a rotina rode. Sem essa marca, a mesma penalidade seria aplicada em todo ciclo.

10. Publicação em massa tem registro próprio (Obrigatório)

Publicar um conteúdo para toda uma comunidade de uma vez gera um registro da publicação em si — não apenas as entregas individuais. A publicação registra qual conteúdo, para qual comunidade, quando e qual o tamanho da audiência; cada entrega gerada aponta para ela.

Isso é obrigatório porque as entregas individuais sozinhas não bastam: a publicação precisa ficar registrada mesmo que nenhum lead seja alvo; o disparo em massa precisa ser idempotente (não publicar duas vezes); e medir alcance e consumo por publicação não pode depender de reconstrução frágil a partir das entregas.

11. Convite a comunidade tem estado único (Obrigatório)

O lead pode ser convidado a uma comunidade. O convite tem estado único, de vocabulário fechado:

none · pending · joined · expired

A wallet guarda quando o lead foi convidado e quantos convites já recebeu. Convite vencido é levado a expired por rotina (mesma disciplina de idempotência da §9: vencer é uma transição, aplicada uma vez). Nenhum fluxo pode usar outra palavra para esses estados.

12. PII do lead na wallet é concessão de v1 (Obrigatório)

Canonicamente, identidade e PII são do identity-service: a wallet referencia o lead por um identity_ref opaco (§8) — que é o person_id cunhado pelo identity (ecosystem.services.identity-person-mint) — e o fato publicado não carrega PII (§6).

Enquanto o identity-service não existe, a wallet guarda nome, CPF, telefone e e-mail do lead — concessão explícita de v1, porque ela precisa contatá-lo para enviar material e convite. Isto é dívida reconhecida: na entrada do Cortex, essa PII migra para o identity-service e a wallet volta a guardar apenas a referência.

Enquanto a concessão durar, valem duas obrigações:

  • Minimização (LGPD): não guardar o que não se usa. O CPF em particular é PII sensível e só se justifica se houver uso real — na dúvida, não guardar.
  • PII não vaza: nunca em evento (§6) e nunca em log. O que sai da wallet é a referência, não a pessoa.

13. Referência ao CRM: a wallet não fala com o Bitrix (Obrigatório)

A wallet guarda o identificador do contato e do negócio no Bitrix, para não ter de localizar o lead por CPF ou telefone a cada atualização (busca lenta e ambígua quando há contatos parecidos). São referências externas: sem FK, validadas pela aplicação (UNISCALE §24.3).

Invariante — é ele que impede o acoplamento: a wallet não chama o Bitrix. Ela entrega a referência ao crm-connector, que é quem integra com o CRM (ECOSYSTEM §4). Guardar o ID é ter informação; chamar o CRM direto seria virar connector — e viola esta regra.


Fronteiras a definir (não inventar)

Itens reconhecidos mas ainda não regrados. Quem precisar deles para e pede a regra — não improvisa.

  • identity-service ainda não existe. O lead é chaveado por identity_ref (a wallet referencia, não cria identidade), mas sem o serviço a resolução é manual e sem FK — e é isso que força a concessão de PII da §12. Quando o identity nascer, define-se o contrato de resolução do ID e a migração da PII.
  • Provisionamento de tenant — fechado: o dono é o institutional (ecosystem.services.institutional-tenant-registry), que distribui por fato. Enquanto a wallet roda antes do Cortex, tenant_id segue preenchido à mão no dev (concessão v1); ao entrar, consome o fato.
  • Consumo tardio (§9). Uma entrega já vencida e penalizada que o lead consome depois: hoje o consumo é registrado e soma os pontos, e a penalidade aplicada permanece. Se o negócio quiser que o consumo tardio não conte, a regra precisa ser escrita — não improvise.
  • Rotina de inatividade (inactive, §5). O estado existe; a rotina agendada que rebaixa lead inativo será escrita depois — quem for implementá-la define a janela e o gatilho.
  • Contrato de leitura do ai-sales (§7). A forma exata do contexto resumido (campos, N de "últimos conteúdos", canal de leitura) é acordada com o ai-sales — não a improvise.
  • RAG / chat sobre o conteúdo. A conversa da IA sobre o material hoje vive no n8n e está fora do banco da wallet. Se internalizar, segue RAG_AND_INGESTION + embedding-service (gateway texto→vetor). Atenção de fronteira: a intenção de "uma query de resumo no embedding-service" conflita com o papel dele (gateway sem geração) — onde a sumarização mora precisa ser decidido antes, sem quebrar a fronteira do embedding-service.

CHANGELOG

Versão Data Resumo
0.2.2 2026-09-24 Editorial (sem mudança de comportamento): fecha a fronteira de provisionamento de tenant — o dono passa a ser o institutional (ecosystem.services.institutional-tenant-registry), que distribui por fato; §8 e a fronteira deixam de dizer "a definir". Enquanto a wallet roda antes do Cortex, tenant_id segue manual no dev (concessão v1). PATCH.
0.2.1 2026-08-31 Editorial (sem mudança de regra): com o identity-service promovido a doc dedicado, esclarece em §12 que o identity_ref opaco é o person_id cunhado pelo identity (ecosystem.services.identity-person-mint). PATCH.
0.2.0 2026-07-14 Reconciliação com o primeiro build real do banco. Muda regra existente: §3 deixa de ser "consumo reportado" e passa a ser "a entrega nasce no envio; o consumo é o desfecho opcional" — envio único por (tenant, lead, conteúdo), reenvio é o mesmo link (não cria entrega, não reinicia prazo), e "não consumido" é ausência, nunca um tipo de consumo; §4 deixa de ser só soma — o score passa a ser pontos consumidos MENOS penalidades, com piso em zero (nunca negativo), e "peso" vira points para casar com o vocabulário de negócio; §5 fecha o vocabulário de estados em engaging/inactive/qualified/student (sai warm, dormant→inactive, entra student) e fixa que o estado é o único critério de elegibilidade de mensagem (recebem engaging e qualified); §2 passa a carregar prazo de consumo e penalidade por material, além de descrição/resumo/tags/comunidades/validade/janela de envio (a "ordem no fluxo" foi removida — não era usada). Regras novas: §9 vencimento sem consumo e penalidade aplicada uma única vez (prazo por material, contado do 1º envio; marca de vencimento garante idempotência); §10 publicação em massa tem registro próprio (registra mesmo sem audiência, dá idempotência ao disparo e permite medir alcance); §11 convite a comunidade com estado único none/pending/joined/expired; §12 PII do lead é concessão de v1 (nome/CPF/telefone/e-mail ficam na wallet só enquanto o identity-service não existe — dívida a migrar, com minimização e proibição de vazar em evento/log); §13 referência ao CRM sem acoplamento (guarda bitrix_contact_id/bitrix_deal_id como referência externa, mas a wallet não chama o Bitrix — passa a ref ao crm-connector). Nova fronteira: consumo tardio (entrega já penalizada que é consumida depois). MINOR.
0.1.0 2026-07-14 Rascunho inicial do ai-wallet (IA de qualificação, via opcional — ECOSYSTEM §4). Fixa: papel/fronteira (qualifica, não vende; insumo de bastidor) (§1); catálogo próprio com byte no storage-service (object_key) ou external_ref externo, e curso-alvo referenciando ID do institutional (§2); consumo reportado pela fonte externa (landing/repo de vídeo), idempotente, sem progresso parcial interno (§3); pontuação = soma dos pesos consumidos, materializada mas recomputável (§4); estados com qualificação por limiar por tenant (§5); fato único ai_wallet.lead.qualified via outbox, payload com identity_ref opaco e sem PII (§6); contexto resumido lido na fonte pelo ai-sales (§7); multi-tenant com tenant_id em toda tabela, aplicando a regra transversal existente uniscale.columns.multi-tenancy (UNISCALE §23.3) (§8). Primeiras regras @rule do serviço (namespace ecosystem, área services). Pendente de revisão.