Elquer Carlos

Kmarote: hardening do KYC com council de IAs, inversão crítica nos contratos e exploração do cadastro sem CPF

Hardening do KYC Didit com council de 4 vozes, bug de sessão duplicada, inversão de colunas em contratos e planejamento do cadastro sem CPF.

A sessão de ontem terminou com uma preocupação concreta: o KYC do Kmarote poderia aprovar um usuário com dados divergentes — Didit retornando um nome, banco com outro, sistema aprovando sem comparar. Hoje virou plano, virou council, virou execução — e no meio do caminho apareceu uma inversão de colunas nos contratos que estava escondida na documentação.

KYC Didit: do plano ao hardening

Plano e council

Antes de mandar qualquer código, fiz o plano formal em docs/planejamento/PLANO_HARDENING_KYC_DIDIT.md (commit b4890ce4). Mas antes de executar, joguei o plano pro /council no Claude Code — quatro vozes avaliando: Skeptic, Pragmatist, Critic e a voz em contexto.

O resultado foi um conjunto de decisões que eu mesmo tomei sobre os pontos ambíguos levantados pelo council:

  • Dados pessoais legais: o usuário não edita mais esses campos diretamente. Edição só via solicitação ao admin por ticket.
  • Aprovação com divergência: quando o Didit retorna Approved, o sistema atualiza os dados do usuário para os dados que o Didit devolveu — e registra a mudança para conhecimento do admin. Nada de aprovar e fingir que os dados já batiam.
  • O council também apontou uma inversão de responsabilidade conta/perfil em alguns itens. Ficou confirmada, com ajuste incorporado ao plano.

Execução do hardening

Os commits vieram em sequência:

  • 9ad3752f — núcleo do hardening: decisão síncrona da verificação, deduplicação e auditoria.
  • ae3d772d — botão de reinício de verificação + polling na tela de KYC enquanto a verificação está em andamento.
  • f27208a7 — retomada de sessão Didit com cooldown para o estado EM_ANALISE e mensagens de erro mais amigáveis.
  • 31d1a4dc — countdown corrigido: o cálculo da idade da sessão agora parte do banco de dados, não do relógio do cliente.

Bug de produção: PDOException 1062

No meio da execução apareceu um bug real: a tela de cadastro estourava PDOException ... 1062 (entrada duplicada) ao criar sessão Didit. O Claude Code rastreou a causa — db_kyc_sessao_criar violava a restrição unique em fluxos de retomada de sessão. O df73199d tornou a função idempotente: se a sessão já existe para aquele usuário, retorna o registro existente em vez de tentar inserir de novo.

Contratos multiperfil: a inversão que estava escondida

Em paralelo, no Codex, pedi uma auditoria do HANDOFF_GESTAO_CONTRATOS_MULTIPERFIL.md. Cobrei que auditoria não é apontar problema genérico — cada item precisava ter arquivo, linha e razão.

A descoberta que justificou o esforço: o significado de usuario_id e criador_id estava invertido entre a documentação e a implementação. O correto é usuario_id ser o dono da conta que gerou o link e criador_id o convidado a assinar quando tem conta — e o código fazia o contrário.

Isso desdobra em:

  • Migration de correção no banco
  • Ajuste no código que lê essas colunas
  • Correção dos contratos já assinados

Também levantei a questão se criador_id não deveria virar perfil_id puxado por username, já que um criador pode ter mais de um perfil. E reafirmei a regra de negócio: só perfil verificado e ativo pode criar contrato.

O resultado ficou registrado em b9681aaf, 856a6b57 e 5eed3d13. A implementação em si fica como tarefa aberta.

Fricção com o Codex no processo

Dois momentos de atrito com o Codex nesta sessão:

  1. O Codex tentou commitar via gh. Cortei: “Já definimos anteriormente como deve ser feito commit e push e não é utilizando gh. Leia na documentação.”
  2. O erro “A leitura agrupada excedeu o limite de 10 segundos” voltou a acontecer. Pedi pra registrar que esse caminho não deve ser usado e qual é o padrão correto (a19b4ba9). Quando o Codex ficou em tentativa e erro tentando achar o caminho alternativo, cobrei: “Leia a documentação e regras de como deve proceder. Não presuma, só faça o que estiver descrito. Caso a ação não tenha um caminho válido registrado, pergunte.”

Regras de processo documentadas

Dois atritos com o Claude Code viraram regra permanente no CLAUDE.md:

  • Tudo no master. O Claude Code fez commit fora do master. Pedi que explicasse o porquê e registrei a regra: todo commit e push vão pro master. O merge foi feito (6a13633a, regra em f97682ea).
  • Leitura local do Codex. A regra de qual caminho usar para leitura de arquivos no Codex ficou documentada formalmente.

Bug modal Grok + 403 CSRF

201b5455 corrigiu o modal do Grok e um 403 de CSRF no painel admin. O devlog não entra em mais detalhes, então o registro fica nessa granularidade.

Cadastro sem CPF: planejado, sem commit

No fim da noite, abri uma frente nova no Claude Code: simplificar o fluxo de cadastro removendo o CPF do processo. A ideia: manter só e-mail, senha, aceite dos termos e referência.

Antes de qualquer código, pedi ao Claude Code que:

  1. Lesse a documentação do fluxo e o cadastro.php
  2. Mapeasse todo lugar onde CPF aparece — banco, validações, telas — para dimensionar o impacto

Detalhes já definidos nesta sessão:

  • Cadastro em uma etapa só, sem confirmação de senha
  • Campo de referência segue oculto, preenchido pela URL, aceitando null

Nada foi commitado. A exploração ficou como base para a próxima sessão.


Estatísticas do dia:

Atividade no PC:

  • Tempo ativo: 5h35min (janela total monitorada: ~21h — AFK domina)

Por categoria (do que ficou ativo):

  • Coding: 2h50min
  • Uncategorized: 1h17min
  • Browsing: 42min
  • Larissa Project: 17min
  • Reading: 11min
  • AI Chat: 11min
  • Communication: 7min

Top apps: Chrome (2h21min) · Antigravity IDE (2h18min) · Codex (48min) · WhatsApp (7min)

Top sites navegados: painel dev Kmarote (17min) · host de banco (10min) · YouTube (8min) · claude.ai (7min) · Instagram (6min)

Trabalho com IA:

  • Conversas claude.ai: 0
  • Sessões Claude Code: 7 sessões · 13 subagents (council + exploração)
  • Sessões Codex: 1 sessão

Código produzido:

  • Commits: 13 (kmaroteApp: 31d1a4dc, f27208a7, 9ad3752f, 5eed3d13, b9681aaf, 856a6b57, a19b4ba9, df73199d, f97682ea, 6a13633a, 201b5455, ae3d772d, b4890ce4)
Fim do ato