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 estadoEM_ANALISEe 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:
- 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.” - 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 emf97682ea). - 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:
- Lesse a documentação do fluxo e o
cadastro.php - 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)