Iago3-stack/ai-bug-triage-system:结合 NLP 与规则引擎的 QA 智能缺陷分诊系统
Iago3-stack/ai-bug-triage-system
GitHub 项目 ai-bug-triage-system 是一个面向 QA 的智能缺陷分诊引擎,用技术关键词与葡萄牙语 NLP 情感分析两层规则自动判定 bug 严重度,并生成 Gherkin 报告。
🌐 English readers: this document is in PT-BR, but your browser can translate it automatically (right-click → "Translate").
Motor de triagem inteligente de bugs desenvolvido para Engenharia de Garantia de Qualidade (QA). Ele combina processamento de linguagem natural (NLP) com lógica de regras para priorizar automaticamente relatos de erros e gerar documentação técnica em formato Gherkin — pronto para copiar para Jira ou GitHub Issues.
⭐ Se esta triagem te ajudou, dá uma estrelinha no projeto — quanto mais estrelas, mais QAs encontram o app na busca do GitHub. É de graça!
- 🔵 Triagem em duas camadas
- Camada técnica: termos críticos (crash, pagamento, login, segurança, 500...) escalam a severidade.
- Camada NLP: análise de sentimento por léxico em português + detecção de negação ("não funciona", "não consigo", "parou de responder"...) + padrões por raiz (regex) — lentidão dispensa enumerar toda flexão (
lento,lenta,lentíssimo,lentamente...) e o lookahead(?!es?\b)exclui o falso positivo lente/lentes.
- 🟣 Análise por IA (Fase 3): se houver chave
GEMINI_API_KEYe o checkbox 🔮 estiver marcado, o app chama o Google Gemini e complementa a triagem com severidade sugerida, categoria, causa raiz provável, passos para reproduzir e resumo técnico — tudo em JSON estruturado, com fallback automático para o Groq (open-weight,gpt-oss-120b) se o Gemini cair (503/429/chave expirada) — ou se o usuário desligar a IA para aquela triagem. Há um seletor de provedor (Automático / Gemini / Groq) para forçar um dos dois — e o botão ➕ Adicionar modelo próprio: traga sua API de qualquer provedor (OpenAI-compatível comogpt-4o, DeepSeek ou um endpoint local — ou um modelo Gemini pago) para testar dentro do app. A chave fica só na sessão (nunca é gravada em disco/histórico). - 🟢 Prioridade final reconciliada: os dois motores são combinados pela regra do maior vence (nenhum alerta grave é ignorado) e o app sinaliza divergência quando discordam, recomendando revisão humana.
- ⚠️ 100% offline e determinístico: o motor
triagem.pyusa apenas a biblioteca padrão do Python — sem API de tradução, sem internet, sem custo e com resultado sempre reproduzível. - 📋 Colar falha bruta e preencher relato sozinho (Pilar 1 de automação) — na Ferramenta, cole um stack trace, log ou a mensagem do usuário e o app extrai título, categoria, módulo, versão, severidade prévia, erro principal (com local do frame) e passos para reproduzir, preenchendo o relato pronto para revisar. 100% local, funciona sem internet e reconhece traces Python, Java, JS/TS, C#/.NET, Go e Ruby.
- 🔷 Transparência de QA: o relatório informa o motor de análise usado e os fatores identificados em cada triagem.
- 💚 Relatório Gherkin (
Dado/Quando/Então) baseado na prioridade detectada. - 🟠 Exportação: baixar relatório (
.md), abrir Issue no GitHub pré-preenchida (ou criar de verdade via API no repositório da sua conta) ou criar issue real no Jira (com prioridade mapeada automaticamente). - ⚪ Histórico da sessão em tabela (
pandas) com opção de limpar. - 📁 Histórico persistido (JSONL local + ☁️ Supabase) — cada triagem vira um snapshot fiel em
data/historico.jsonl(local, gitignored); quando o Supabase está configurado (URL + anon key nos secrets), o histórico passa a viver na nuvem e sobrevive a redeploys (com failover automático pra JSONL se a nuvem cair). Seletor de data + download do relatório em Markdown + vínculo com a issue criada no Jira. Backend visível no expander do histórico. - 🛡️ Guardrails de entrada/saída (PII) — detecta e mascara token Atlassian, chaves Gemini/Google/OpenAI, tokens GitHub, e-mails, senhas numéricas, telefones e CPFs digitados no relato: nada sensível vai para o Gemini, o Jira, o GitHub ou o histórico.
- 🧪 Testes + CI — suíte
pytestcom dezenas de arquivos (motor, colar falha, Jira, persistência, guardrails, dashboard, RAG, nuvem, Pix, IA, Auth/Supabase, notificações, plano e persistência de sessão) rodando a cada push via GitHub Actions. A contagem exata de testes aprovados aparece no badge dinâmico acima (atualiza automaticamente a cada CI) — veja o número atual ao vivo emai-bug-triage.com.br. - 📈 Dashboard de QA completo — visão geral 100% local do histórico (JSONL/cloud), sem enviar nada: KPIs + saúde da suíte (0–10), gauge de % de críticas/altas, filtro por funcionalidade, evolução do score médio por dia, top causas raiz da IA, taxa + lista das divergências IA vs. léxico e coluna IA com o provedor real que respondeu.
- 📚 RAG no histórico — o Gemini consulta as triagens passadas (retrieval híbrido local: BM25 com IDF, ponderação por campo, sinônimos PT-BR e bônus de recência/resolução, com rerank vetorial opcional por embeddings Gemini quando há chave) e responde se o problema já aconteceu e como foi resolvido antes, apontando os registros similares. Sem chave ou sem rede, o retrieval lexical funciona sozinho — nunca quebra o app. Depois de resolver o bug, registre a solução no app — vira aprendizado para as próximas triagens similares.
- 🟦 Rodapé de doação Pix — card no rodapé do app com o símbolo oficial do Banco Central (SVG inline, teal — sem depender de serviço externo), botão "Pagar com Pix via link" e QR Code com a chave com
+55(payload EMV/CRC válido) + botão que copia a chave sem o DDI (os apps de banco completam sozinhos). Tudo dentro de um iframe local do Streamlit (st.iframe). - 🟫 Sem falsos positivos técnicos: palavras como erro, bug e falha são vocabulário normal de teste e não disparam severidade sozinhas.
- 🟥 Interface com identidade visual própria (tema Streamlit em
config.toml). - 🔐 Login real (Supabase Auth, multi-tenant) — cadastro com confirmação de e-mail e login (e-mail + senha); Início público, Ferramenta e Dashboard exigem login quando o Supabase está configurado (sem config, o app segue aberto). Sidebar mostra 👤 usuário + "Sair". Cada conta vê só o seu histórico (registros persistidos com
tenant_id). - 🔄 Sessão persiste no F5 — ao recarregar a página, o usuário continua logado: cookie
_auth_sessao_persist_rf+ "ponte de escrita" persistente (JSON → iframelocalStorage→ confirm), com falha degradando para tela de login com mensagem honesta.
| Camada | Tecnologia | Por quê |
|---|---|---|
| Motor de severidade | Python stdlib (re, sem dependência) |
Roda offline, custo zero e resultado reproduzível — nenhum resultado depende de rede ou de modelo |
| Interface | Streamlit 1.64 | Entrega rápida sem manter front-end; st.navigation com 7 páginas |
| Análise por IA | Gemini (google-genai) com fallback Groq |
Causa raiz e passos de reprodução; se um provedor cai (503/429), o outro assume |
| Dados | pandas 3.0.6 para histórico em tela | Tabela de triagens e KPIs do Dashboard |
| Persistência | Supabase (REST) com failover para JSONL | Histórico sobrevive a redeploy; se a nuvem cair, degrada para arquivo local em vez de perder dado |
| Auth | Supabase Auth via REST | Multi-tenant sem gerenciar senha |
| Pagamento | PagBank Pix + webhook assinado | Cobrança com verificação de assinatura; confirmação idempotente |
| Testes | pytest (741) + Semgrep no CI | Regressão travada a cada push; regra de comparação em tempo constante (CWE-208) como gate |
Por que léxico e não embeddings
Severidade é impacto de negócio, não similaridade semântica — e isso foi medido, não assumido. Dois experimentos de ML no histórico do projeto, mesmo corpus de 30 relatos rotulados:
| Motor | Tolerante | Estrito |
|---|---|---|
| Léxico local (em produção) | 96,7% | 95,7% |
| Protótipos (zero-shot, transformers) | 53,3% | 43,5% |
| 1-NN treinado | 66,7% | 60,9% |
| TF-IDF + centroides (sem transformer) | 53,3% | 39,1% |
O dado que fecha a discussão: TF-IDF sem transformer empatou com os transformers — o gargalo é a quantidade de dado rotulado, não a capacidade do modelo. O motor léxico ficou, é mais leve e é determinístico. Detalhes em 03 — Arquitetura.
git clone https://github.com/Iago3-stack/ai-bug-triage-system.git # 📥 clona o repo cd ai-bug-triage-system # 📂 entra na pasta python3 -m venv .venv # 🐍 cria o ambiente virtual source .venv/bin/activate # ⚡ ativa o venv pip install -r requirements.txt # 📦 instala as dependências streamlit run home.py # 🚀 roda a aplicação
A análise por IA usa a chave GEMINI_API_KEY (gratuita em aistudio.google.com/apikey). Sem a chave, o app funciona normalmente só com o motor local:
- 🔑 Local: crie um arquivo
.envna raiz comGEMINI_API_KEY=...(ele é ignorado pelo.gitignore). - ☁️ Streamlit Cloud:
Settings → Secrets → GEMINI_API_KEY(nunca coloque a chave em código ou no repositório).
🧪 Rodar os testes — a mesma suíte do CI (814 testes, número exato no badge dinâmico):
pip install -r requirements-dev.txt pytest -q # suíte completa pytest test_triagem.py -v # um módulo só
🔔 Rodar o webhook localmente (Pilar 3 — recebe a falha direto do CI):
python webhook.py --porta 8080 --host 0.0.0.0 curl -s localhost:8080/health
🔐 Variáveis de ambiente — todas opcionais (sem nenhuma delas o app roda só com o motor local):
| Variável | Para quê |
|---|---|
GEMINI_API_KEY |
Análise por IA (Fase 3) — chave gratuita do Google AI Studio |
SUPABASE_URL + SUPABASE_ANON_KEY |
Login multi-tenant + histórico na nuvem |
JIRA_EMAIL, JIRA_API_TOKEN, JIRA_PROJECT_KEY, JIRA_URL |
Exportação para o Jira |
ALERTA_EMAIL_TO, SMTP_USER, SMTP_PASS (+ SMTP_HOST/SMTP_PORT) |
Alertas de triagem CRÍTICA/ALTA por e-mail |
DISCORD_WEBHOOK |
Alertas por Discord |
WEBHOOK_TOKEN (+ WEBHOOK_REQUIRE_TOKEN=1) |
Autentica o webhook de CI (comparação em tempo constante) |
PAGBANK_TOKEN |
Cobrança Pix automática |
POSTHOG_API_KEY |
Telemetria anônima (sem PII e sem conteúdo do relato) |
ALLOW_LOCAL_MODELS=1 |
Libera só loopback na Base URL do modelo próprio (ex.: Ollama http://localhost:11434/v1); destino privado continua bloqueado e a cloud deixa apagado |
🔑 Segredo nunca no git: localmente em .env (ignorado pelo .gitignore); no Streamlit
Cloud em Settings → Secrets. Listas completas em 05 — Persistência em Nuvem,
06 — Webhook e 07 — Segurança.
Para desenvolver com agentes (MCPs do Supabase/Render/semgrep), veja a seção 5 de
03 — Arquitetura.
💳 Webhook do PagBank (assinatura verificada)
O webhook é um micro-serviço HTTP 100% stdlib (webhook.py) — sem Flask, sem FastAPI, sem dependência. Ele recebe a confirmação de pagamento do PagBank e só libera o acesso quando a requisição é autêntica.
A assinatura não é um header customizado. A conta do PagBank não permite header customizado: os documentados são x-authenticity-token, x-product-origin e x-product-id. A doc oficial define a assinatura como:
x-authenticity-token = SHA256(token_da_conta + "-" + corpo_cru) # hex
Três detalhes que costumam ser o erro de quem implementa:
- O hash é sobre os bytes crus do corpo. Reserializar o JSON já parseado muda o espaçamento e a validação falha sempre.
- A comparação é em tempo constante (
hmac.compare_digest) —==é vetor de timing (CWE-208), e é isso que o Semgrep do CI bloqueia. - O token que protege
/webhook/falha(WEBHOOK_TOKEN) não serviria aqui: ele nunca chega nessa rota.
Como defesa em profundidade: mesmo com corpo forjado, nada é confirmado sem a consulta server-side na API do PagBank. A confirmação (pixbilling.confirmar_cobranca) é idempotente — reenvio do PagBank não duplica cobrança.
As duas rotas têm teto de payload (MAX_BYTES, validado no Content-Length antes de ler) e timeout de socket (30s); o 413 fecha a conexão em vez de deixar corpo não drenado sujar o socket sob keep-alive.
⚠️ Estado atual: a cobrança automática está desligada — a API do PagBank responde
403 ACCESS_DENIEDaté a whitelist cair. O endpoint já está endurecido antes disso. ⚠️ Recorrência: a doc pública dizx-authenticity-token, mas há relatos no fórum do PagBank de receberX-Payload-Signature(RSA) em produção. A rota valida o header documentado; se a recorrência for ativada, confirmar o header real em produção antes de confiar na validação.
🔔 Alerta de triagens CRÍTICAS/ALTAS (e-mail ou Discord)
Quando uma triagem resulta em CRÍTICA 🚨 ou ALTA 🚨, o app avisa automaticamente — vira "monitor de QA". Dois canais (pode configurar os dois):
✉️ E-mail (Gmail/SMTP) — não precisa criar conta nova:
- No Google, ative a "verificação em 2 etapas" e gere um app password em
https://myaccount.google.com/apppasswords(a senha do Gmail normal não funciona no SMTP). - Configure nos Secrets (Cloud) ou
.env(local):ALERTA_EMAIL_TO(para onde chega o alerta),SMTP_USER(seu Gmail) eSMTP_PASS(o app password). Opcionais:SMTP_HOST/SMTP_PORT(padrãosmtp.gmail.com:587).
🔔 Discord (opcional): servidor/canal → Configurações → Integrações → Webhooks → Novo webhook → copie a URL e configure DISCORD_WEBHOOK (https://discord.com/api/webhooks/...).
Sem canal configurado (ou em falha de rede), o alerta é silencioso — nunca interrompe a triagem.
🔗 Exportação para o Jira (API REST)
O botão 📋 Exportar para Jira cria a issue do tipo Tarefa direto no seu projeto Jira Cloud. Você configura de dois jeitos:
- 🖱️ Pela interface: no app, abra
🔑 Jira — configurar exportaçãono sidebar e preencha e-mail Atlassian, API Token e chave do projeto. Basta login+token (Basic Auth) — não é preciso OAuth nem senha. - ⚙️ Por variáveis de ambiente (
.envou Streamlit Secrets):JIRA_EMAIL,JIRA_API_TOKEN,JIRA_PROJECT_KEYe, opcionalmente,JIRA_URL(padrãohttps://iagoqa.atlassian.net).
🔑 Para gerar o API Token: acesse https://id.atlassian.com/manage-profile/security/api-tokens → Create API token → copie o token (ele só aparece uma vez). A chave do projeto (ex.: KAN para "Rastreamento de bugs") aparece na URL do seu projeto: https://iagoqa.atlassian.net/browse/KAN-4 → KAN.
Tipo de item (importante): o app assume Tarefa por padrão (compatível com projetos Kanban, onde Bug não existe). Os tipos válidos do template Kanban são: Tarefa, História, Epic, Subtask. Para outro projeto, troque via JIRA_ISSUE_TYPE.
Prioridades mapeadas automaticamente: NORMAL ✅ → Low · MÉDIA ⚠️ → Medium · ALTA 🚨 → High · CRÍTICA 🚨 → Highest.
🧪 Teste rápido do cliente sem interface (python jira_client.py) — exige as credenciais no ambiente:
python jira_client.py # 🧪 cria uma issue de teste via API🐙 Exportação para o GitHub Issues (API REST)
O botão 🐙 Criar Issue no GitHub cria a issue de verdade no repositório da sua conta/empresa — o Jira continua sendo a via do time. São dois caminhos:
- 🖱️ Sem token (padrão): o botão vira link 🐙 Nova Issue no GitHub já preenchido (título + relato) — abre o formulário no navegador para você revisar e enviar.
- 🔑 Com token: em
⚙️ Configurações → 🐙 GitHub — configurar repositório para issuesvocê informa o token e odono/repode destino. Aí o app chamaPOST https://api.github.com/repos/{dono}/{repo}/issuese mostra o link da issue criada.
Escopo do token: fine-grained → Issues: Read and write no repositório escolhido;
classic → repo (ou public_repo se for público). Token e repositório ficam só na
sessão (st.session_state) — nada em disco, banco ou histórico — e o botão
↩️ Limpar minha config do GitHub apaga na hora.
A criação não envia labels (label inexistente retorna 422) e os erros vêm traduzidos:
404 → repositório/escopo errado · 401/403 → token sem permissão Issues: write.
🧪 Teste rápido do cliente sem interface — com token e repo no ambiente:
python -c "import github_client; print(github_client.configurado({'token': 'ghp_...', 'repo': 'dono/repo'}))"🧪 Teste rápido dos motores sem interface
python triagem.py # 🟢 motor determinístico local python ia.py # 🔮 análise por IA (Gemini) — exige a chave
🧩 Conheça a engenharia por trás do AI Bug Triage System — o processo completo de requisitos, casos de teste e estratégia de QA está em 📚 docs/.
| Arquivo | Papel |
|---|---|
🖥️ home.py |
Interface web (Streamlit): cabeçalho, ferramenta, export, histórico e rodapé de doação Pix via st.iframe |
🧠 triagem.py |
Motor NLP: léxico PT, padrões de negação e classificação de severidade (offline) |
🔗 jira_client.py |
Cliente da API REST v3 do Jira: cria issues (Tarefa) com prioridade mapeada — credenciais por sessão (st.session_state), sem global de módulo |
🐙 github_client.py |
Cliente da API REST do GitHub: cria issues no repo da sua conta via POST /repos/{dono}/{repo}/issues, sem labels (evita 422), erros amigáveis (404/401/403) — token só na sessão |
🔌 webhook.py |
Micro-serviço HTTP 100% stdlib que recebe a confirmação do PagBank. Valida x-authenticity-token (SHA256(token + "-" + corpo_cru), tempo constante) sobre os bytes crus, tem teto de MAX_BYTES no Content-Length, timeout de 30s e 413 que fecha a conexão. Também serve /webhook/falha para CI |
💳 pixbilling.py |
Cobrança Pix no PagBank: gera a cobrança, referencia a triagem (cob-…) e confirma de forma idempotente (reenvio do PagBank não duplica) |
🧪 test_webhook.py |
Testes do webhook: assinatura válida/inválida, corpo cru vs. reparse, teto de payload, timeout e o parsing do payload de pagamento |
🧪 test_github_client.py |
18 testes do cliente GitHub: normalização de dono/repo (URL/.git), config por sessão, payload sem labels e erros amigáveis (rodam no CI) |
🔮 ia.py |
Análise por IA via Google Gemini: causa raiz, categoria e passos (com fallback Groq e modelo próprio OpenAI-compatível/Gemini) |
📚 rag.py |
RAG no histórico, sem banco vetorial: retrieval BM25 com IDF (texto ponderado por campo, sinônimos PT-BR, bônus de recência/resolução — offline e determinístico) + rerank vetorial opcional por embeddings Gemini com cache em RAM/JSONL (0.6×cosseno + 0.4×BM25, cai silencioso para o lexical) e geração que responde "já aconteceu? como resolvemos?" |
🧪 test_triagem.py |
90 testes unitários do motor (rodam no CI) |
🧪 test_jira_client.py |
18 testes unitários do cliente Jira (rodam no CI) |
📁 persistencia.py |
Histórico em data/historico.jsonl (JSONL local, gitignored) — facade: com nuvem configurada, grava no Supabase; senão, JSONL puro |
☁️ nuvem_supabase.py |
Backend de persistência na nuvem (Supabase REST): insert/select/update e vínculo Jira — credenciais só em secrets/.env |
🛡️ guardrails.py |
Bloqueia vazamento de credenciais/PII: mascara tokens, chaves, e-mails, senhas numéricas, telefones e CPFs antes de IA/Jira/GitHub/histórico |
🧪 test_persistencia.py |
15 testes unitários da persistência (rodam no CI) |
🧪 test_guardrails.py |
18 testes de detecção/máscara de credenciais e PII (rodam no CI) |
🧪 test_dashboard.py |
17 testes do Dashboard de QA: saúde da suíte, gauge, filtro por funcionalidade, top causas, divergências e provedor real (rodam no CI) |
🧪 test_rag.py |
23 testes do RAG: tokenização, Jaccard, BM25, sinônimos, recência/resolução, rerank vetorial híbrido com vetores mockados, contexto (com resolução) e orquestração sem chave (rodam no CI) |
🧪 test_nuvem_supabase.py |
38 testes da persistência em nuvem: config, conversão, HTTP (mockado), resolução, failover e dispatch do facade (rodam no CI) |
🧪 test_pix.py |
10 testes do Pix: payload EMV, CRC-CCITT, precedência link/QR e chave_copia() sem +55 (rodam no CI) |
🧪 test_ia.py |
38 testes da IA: dispatch de provedor (auto/Gemini/Groq/modelo próprio OpenAI-compatível e Gemini custom), JSON, fallback, mensagens de erro e orquestração RAG (rodam no CI) |
🔐 auth_supabase.py |
Autenticação (Supabase Auth/GoTrue via REST, stdlib): cadastro com confirmação, login e logout — credenciais reutilizam SUPABASE_URL/SUPABASE_ANON_KEY |
🧪 test_auth_supabase.py |
46 testes do login: parser de erros, cadastro/login/logout, isolação por sessão e integração com a UI (rodam no CI) |
🔔 notificacoes.py |
Canais de alerta (e-mail SMTP + Discord) configuráveis por usuário/sessão, com testadores à prova de exceção |
🧪 test_notificacoes.py |
45 testes dos alertas: envio SMTP/Discord (mockado), override por sessão e erros amigáveis (rodam no CI) |
💳 plano.py |
Planos Basic/Premium e isolamento por tenant: `PLANO=free |
🧪 test_plano.py |
48 testes do plano: gating de recursos free×pago e filtro por tenant_id (rodam no CI) |
💾 sessao_persist.py |
Persistência de sessão no F5: enfileira salvar/limpar e grava via ponte persistente (cookie + iframe localStorage) |
🧪 test_sessao_persist.py |
8 testes da ponte de escrita e da failover da sessão (rodam no CI) |
🧪 test_ferramenta.py |
12 testes da página ferramenta: UI/triagem e integração (rodam no CI) |
📈 dashboard.py |
Dashboard de QA: KPIs + saúde da suíte (0–10) + gauge de críticas + filtro por funcionalidade + top causas (IA) + score/dia + divergências IA vs. léxico + provedor real (leitura do JSONL/Cloud) |
🟦 pix.py |
Gerador de pagamento Pix: payload EMV/QR (CRC-CCITT), QR Code PNG (base64), link de pagamento com valor fixo e chaves com/sem +55 (chave/chave_copia) |
📦 requirements.txt |
Dependências pinadas |
🎨 .streamlit/config.toml |
Tema e configurações da app |
📚 docs/ |
Documentação de engenharia e qualidade |
- ✅ Fase 1 — Motor NLP offline (léxico PT + negação, sem TextBlob/Google Translate)
- ✅ Fase 2 — Exportação do relatório, histórico de sessão e identidade visual
- ✅ Fase 3 — Integração com LLMs (Gemini) para análise de causa raiz, categoria e passos — com fallback automático
- ✅ Seletor de IA por triagem (checkbox 🔮 + provedor) — você decide quando a IA entra: desligue para triagem 100% local, ou escolha Automático (Gemini → Groq), só Gemini ou só Groq — ou ➕ adicione um modelo próprio com a sua API (OpenAI-compatível ou Gemini pago), renomeável e editável, com chave que fica só na sessão. O relatório mostra qual provedor/modelo respondeu
- ✅ Testes unitários do motor (
pytest) — suíte extensa de arquivos (motor + Jira + persistência + guardrails + dashboard + RAG + nuvem + Pix + IA + Auth/Supabase + notificações + plano + persistência de sessão) rodando automaticamente via CI (GitHub Actions) com contagem exibida ao vivo no badge dinâmico acima - ✅ Exportação via API do Jira — cria issue do tipo Tarefa no
iagoqa.atlassian.net(prioridade mapeada automaticamente) - ✅ Exportação via API do GitHub Issues — cada conta/empresa cria issue no seu repositório (
POST /repos/{dono}/{repo}/issues, token só na sessão, sem labels para evitar 422); sem token, abre o link de issue já preenchida - ✅ Persistência do histórico (JSONL) — cada triagem vira um snapshot fiel em
data/historico.jsonl(local, gitignored): com IA salva o relatório completo; sem IA, só o léxico. Seletor de data + download do relatório - ✅ Guardrails de entrada/saída (PII/credenciais) — detecta e mascara tokens Atlassian, chaves Gemini/Google/OpenAI, tokens GitHub, e-mails, senhas numéricas, telefones e CPFs digitados no relato: nada sensível vai para o Gemini, o Jira, o GitHub ou o histórico
- ✅ Dashboard de QA completo — saúde da suíte (0–10), gauge de % de críticas/altas, filtro por funcionalidade, evolução do score médio/dia, top causas raiz (IA), taxa + lista das divergências IA vs. motor local e provedor real na coluna IA (100% local, sem enviar nada)
- ✅ RAG no histórico — o Gemini consulta as triagens passadas (top-k similares, retrieval híbrido BM25 + vetores, com sinônimos e ponderação por recência/resolução, degradando para o lexical sem chave de embeddings) e responde "isso já aconteceu? como resolvemos?" com a resolução anterior; se não acha, sinaliza caso novo
- ✅ Alerta CRÍTICA/ALTA (e-mail SMTP + Discord) — "monitor de QA": canais configuráveis por sessão no modal ⚙️ (nada em disco), com testadores que nunca derrubam o app e status real do envio
- ✅ App multi-página + Login multi-tenant —
Início/Triagem/Dashboardviast.navigation; cadastro com confirmação de e-mail e login (Supabase Auth); histórico isolado por conta (tenant_id); sessão persiste no F5 (cookie + ponte) - ✅ Roadmap 13/13 🎉 — MVP + SaaS esboçado concluídos; próximos passos rumo a billing/compartilhamento abaixo
🚀 Rumo a um SaaS de QA (próximos passos):
- 💳 Assinatura/billing (Stripe) ligada ao
PLANOatual + cobrança por plano pago (PASSO 4)- 🧠 Causa raiz com histórico (evolução do RAG ✅) → sugerir a correção que resolveu da última vez → triage agent
- 🔁 Limpeza de warnings de deprecação do Streamlit (
use_container_width→width='stretch')- 🌐 webhook/API · 📧 relatório agendado · 📊 LLMOps/evals
- Roadmap completo acompanhado no documento de brainstorming do projeto (local, fora do repo).
Persistência em nuvem ☁️, login 🔐 e modelo alternativo (Groq) 🔁 já estão feitos (v2.6.x).
🧑💻 Autor: Iago Nunes (Iago3-stack) — QA Automation Engineer | Estudante de IA & Machine Learning na UNIASSELVI.
📜 Este projeto é distribuído sob a licença MIT (ver arquivo LICENSE). Qualquer uso, cópia ou modificação deve manter a atribuição de crédito ao autor original — remover ou ocultar a autoria viola a licença. Veja AUTORIA.md para a origem e as provas públicas de autoria.
🕓 O histórico completo de construção (commits, datas e motivações) está público em github.com/Iago3-stack/ai-bug-triage-system.
来源:GitHub · github.com
