feat: add dev workflows as agent skills

Four SKILL.md-based workflows for agent-driven development: frontend/UI,
backend/API, architecture, and security code review.

Each workflow defines phases with verification steps, acceptance criteria
and hard rules so agents deliver work that can be checked instead of
asserted. The security review consults live sources (OSV.dev, GitHub
Advisory, NVD) because model CVE knowledge is frozen at training cutoff.

Includes a QA harness (qa/) that scores workflows on 30+ criteria, a
non-regression gate, and meta-tests that corrupt the harness to prove it
detects regressions.
This commit is contained in:
Evandro Fonseca Junior committed 2026-08-19 05:22:09 -03:00
commit 722c544b72
13 files changed
+2193

No files matched your search

+4
View File
@@ -0,0 +1,4 @@
__pycache__/
*.pyc
.venv/
node_modules/
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 Evandro Fonseca Junior
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+79
View File
@@ -0,0 +1,79 @@
# dev-workflows
Workflows de desenvolvimento que uso no dia a dia, codificados como skills
de agente (formato SKILL.md). Cada um define um processo com fases, passos
de verificação, comandos reais e regras duras - daí sai trabalho consistente
em vez de "confia em mim".
Em geral mexo com Node/TypeScript, NestJS, PostgreSQL, Docker e front em
React. Os workflows refletem isso, mas as fases são neutras o suficiente
pra servir em outros stacks.
## O que tem aqui
| Workflow | Para quê |
|---|---|
| [wf-frontend](workflows/wf-frontend.md) | UI/design/PDF: direção visual antes de codar, anti-AI-slop, perf React, QA visual |
| [wf-backend](workflows/wf-backend.md) | API/backend: contrato antes do handler, defaults seguros, auditoria OWASP, testes |
| [wf-architecture](workflows/wf-architecture.md) | Arquitetura: requisitos mensuráveis, C4, ADR, threat model, revisão |
| [wf-security-review](workflows/wf-security-review.md) | Code review de segurança front+back: CVE conhecidas + consulta de novas (OSV/NVD/GH Advisory) |
Cada SKILL.md funciona no Hermes Agent (e em qualquer agente que leia o
formato): a descrição no frontmatter é o gatilho - quando o contexto bate,
o fluxo carrega sozinho.
## Por que fases com verificação
O problema que isso resolve: agente "acha que fez" mas não tem como provar.
Cada fase termina com passos de verificação (rodar build, rodar teste,
consultar OSV.dev) e os workflows têm critérios de aceite. Sem evidência,
não entrega.
Tem um harness de qualidade no `qa/` que mede isso de forma objetiva:
```bash
cd qa
python3 wf_quality_harness.py # score por workflow (30+ critérios)
python3 test_quality.py # gates: não-regressão, skills válidas, verificação por fase
python3 test_tests.py # teste dos testes: muta e confirma que o harness detecta
```
O `test_tests.py` é o diferencial: ele corrompe o harness e os workflows de
propósito e confirma que o score cai. Se o score não muda com a corrupção,
o detetor é inútil. Isso está sempre verde.
## Segurança: não confiar no cutoff
A skill de segurança tem uma regra dura: o modelo conhece CVE só até o
cutoff de treino. Então "não tem vulnerabilidade" nunca é resposta de
memória - o workflow consulta fontes vivas:
- OSV.dev via safedeps (CVE em tempo real por `package@version`)
- GitHub Advisory Database (via gh api)
- NVD
Leva 3 skills de segurança de fontes primárias (OWASP, OSV.dev, UnitOne
SecuritySkills) e as usa como pilares do review.
## Instalação
Copie os arquivos de `workflows/` para o diretório de skills do seu agente:
```bash
# Hermes Agent
cp workflows/*.md ~/.hermes/skills/software-development/
# Claude Code / agentes com skills dir
mkdir -p ~/.claude/skills && cp workflows/*.md ~/.claude/skills/
```
Para o `wf-security-review`, instale também a skill safedeps e o script
`check_deps.py` (veja `docs/SKILLS.md`) - é o que consulta o OSV.dev.
## Docs
- [docs/SKILLS.md](docs/SKILLS.md) - lista completa das skills usadas,
origem de cada uma e como instalá-las
- [qa/](qa/) - harness de qualidade + gates + teste dos testes
Licença: MIT.
+86
View File
@@ -0,0 +1,86 @@
# Skills usadas e de onde vieram
Este é o inventário do que os workflows carregam. Cada skill é um diretório
com um `SKILL.md`; para o Hermes Agent, vão em `~/.hermes/skills/`.
## Pilar de segurança (wf-security-review)
| Skill | Origem | O que faz |
|---|---|---|
| `safedeps` | [Jeneidi/safedeps](https://github.com/Jeneidi/safedeps) | Consulta OSV.dev em tempo real; CVE por `package@version` com severidade e versão de fix. Inclui o script `check_deps.py` |
| `sca-audit` | [OWASP/secure-agent-playbook](https://github.com/OWASP/secure-agent-playbook) | SCA de dependências com análise de alcance (reachability), mapeamento CWE |
| `code-review-security` | OWASP/secure-agent-playbook | Code review de segurança sistemático mapeado a OWASP Top 10 + ASVS |
| `secrets-scan` | OWASP/secure-agent-playbook | Detecta credenciais/API keys no código e no git history |
| `api-security-review` | OWASP/secure-agent-playbook | Revisão de API contra OWASP API Security Top 10 |
| `web-security-review` | OWASP/secure-agent-playbook | Web app contra OWASP Top 10 (2021) |
| `cve-triage` | [UnitOneAI/SecuritySkills](https://github.com/UnitOneAI/SecuritySkills) | Prioriza CVE por CVSS 4.0 / EPSS / CISA KEV |
| `patch-prioritization` | UnitOneAI/SecuritySkills | Decide a ordem de remediação |
| `dependency-scanning` | UnitOneAI/SecuritySkills | Varredura de dependências |
## Frontend / UI / design (wf-frontend)
| Skill | Origem | O que faz |
|---|---|---|
| `frontend-design` | [anthropics/skills](https://github.com/anthropics/skills) | Direção visual, tipografia, fugir do genérico |
| `web-design` | [KAOPU-XiaoPu/web-design](https://github.com/KAOPU-XiaoPu/web-design) | Estética web coesa |
| `vercel-react-best-practices` | [vercel-labs/agent-skills](https://github.com/vercel-labs/agent-skills) | 40+ regras de perf React/Next |
| `vercel-composition-patterns` | vercel-labs/agent-skills | Compound components, composição |
| `animate` | [emilkowalski/skill](https://github.com/emilkowalski/skill) | Motion com propósito |
| `anti-ai-slop` | local | Detecta padrão visual "gerado por IA" |
| `avoid-ai-writing` | [conorbronsdon/avoid-ai-writing](https://github.com/conorbronsdon/avoid-ai-writing) | Remove AI-isms de texto/microcopy |
## Backend / API (wf-backend)
| Skill | Origem | O que faz |
|---|---|---|
| `secure-coding` | [v6x/secure-coding-skill](https://github.com/securityreviewai/secure-coding-skill) | Padrões de codificação segura em 15 stacks |
| `bola-detector` | [apisec-inc/apisec-skills](https://github.com/apisec-inc/apisec-skills) | Detecta object-level authorization (OWASP API1) |
| `auth-rbac-scaffold` | apisec-inc/apisec-skills | Auth/RBAC (OWASP API2/API5) |
| `injection-checker` | apisec-inc/apisec-skills | Injection SQL/ORM/shell (OWASP API8) |
| `openapi-hardener` | apisec-inc/apisec-skills | Saneia schemas OpenAPI/Zod (OWASP API3) |
| `api-security-review` | apisec-inc/apisec-skills | Review completo OWASP API Top 10 |
| `security-test-generator` | apisec-inc/apisec-skills | Gera testes de segurança |
## Arquitetura (wf-architecture)
| Skill | Origem | O que faz |
|---|---|---|
| `system-design` | [Kotivskyi/architecture-governance-skills](https://github.com/Kotivskyi/architecture-governance-skills) | Framework HelloInterview de system design |
| `c4-architecture` | Kotivskyi/architecture-governance-skills | Diagramas C4 (Mermaid/Structurizr) |
| `isaqb-architecture-governance` | Kotivskyi/architecture-governance-skills | arc42 + ADR |
| `secure-architecture-governance` | Kotivskyi/architecture-governance-skills | Threat model STRIDE+CIA, S-ADR |
## Caça de bugs (todas)
| Skill | Origem | O que faz |
|---|---|---|
| `hermaguard` | [Sahil-SS9/hermaguard](https://github.com/Sahil-SS9/hermaguard) | Review adversarial: pre-scan + 3 agentes (edge cases, ataque, blast radius) |
## Como instalar as skills de origem
A maioria instala via `npx skills` (formato agentskills.io):
```bash
npx skills add anthropics/skills --skill frontend-design
npx skills add vercel-labs/agent-skills --skill vercel-react-best-practices
npx skills add conorbronsdon/avoid-ai-writing
```
As de segurança do OWASP e UnitOne instalam clonando e copiando o diretório
da skill:
```bash
git clone --depth 1 https://github.com/OWASP/secure-agent-playbook.git
cp -r secure-agent-playbook/plugins/code-security-skills/skills/{sca-audit,secrets-scan} ~/.hermes/skills/
git clone --depth 1 https://github.com/UnitOneAI/SecuritySkills.git
cp -r SecuritySkills/skills/vuln-management/{cve-triage,patch-prioritization} ~/.hermes/skills/
```
O safedeps precisa do script junto da skill:
```bash
git clone --depth 1 https://github.com/Jeneidi/safedeps.git
cp -r safedeps/skills/safedeps ~/.hermes/skills/safedeps
cp safedeps/check_deps.py ~/.hermes/skills/safedeps/
```
+236
View File
@@ -0,0 +1,236 @@
{
"workflows": [
{
"name": "wf-frontend",
"score": 385.5,
"skills_referenciadas": [
"animate",
"anti-ai-slop",
"avoid-ai-writing",
"claude-design",
"design-md",
"frontend-award-tier",
"frontend-design",
"hermaguard",
"html-css-print-engineer",
"pdf-generator",
"pdf-render-qa",
"pdf-visual-designer",
"popular-web-designs",
"professional-pdf-director",
"sketch",
"vercel-composition-patterns",
"vercel-react-best-practices",
"web-design"
],
"criteria": {
"frontmatter": 5,
"when_to_use": 8,
"num_fases": 6,
"regras_duras": 10,
"n_regras": 9,
"fase1": 16,
"fase2": 16,
"fase3": 16,
"cobertura_fases": 20,
"skills_validas": 15,
"fase_rotulos": 6,
"fase_acao": 6,
"fase_revisao": 6,
"anti_slop": 4.5,
"cmd_blocos": 8,
"cmd_reais": 5,
"sec_criterios": 8,
"sec_verificar": 6,
"sec_nao_regressao": 6,
"tamanho": 8,
"testes_referidos": 5,
"passos_total": 30,
"verificacao_total": 24,
"comandos_reais": 20,
"profundidade": 10,
"por_fase_verif": 18,
"por_fase_cmd": 18,
"por_fase_antip": 12,
"por_fase_aceite": 12,
"exemplos": 10,
"exemplos_count": 12,
"artefatos": 14,
"fluxo": 8,
"entradas_saidas": 8
}
},
{
"name": "wf-backend",
"score": 424.0,
"skills_referenciadas": [
"api-security-review",
"auth-rbac-scaffold",
"bola-detector",
"dependency-cve-audit",
"fastapi-uvicorn-wiring",
"hermaguard",
"injection-checker",
"network-audit",
"openapi-hardener",
"rest-graphql-debug",
"secure-coding",
"security-best-practices",
"security-test-generator",
"software-code-quality",
"test-driven-development"
],
"criteria": {
"frontmatter": 5,
"when_to_use": 8,
"num_fases": 8,
"regras_duras": 10,
"n_regras": 10,
"fase1": 15,
"fase2": 15,
"fase3": 16,
"fase4": 16,
"cobertura_fases": 20,
"skills_validas": 15,
"fase_rotulos": 6,
"fase_acao": 6,
"fase_revisao": 6,
"anti_slop": 5.0,
"cmd_blocos": 8,
"cmd_reais": 5,
"sec_criterios": 8,
"sec_verificar": 6,
"sec_nao_regressao": 6,
"tamanho": 8,
"testes_referidos": 5,
"passos_total": 30,
"verificacao_total": 24,
"comandos_reais": 20,
"profundidade": 13,
"por_fase_verif": 22,
"por_fase_cmd": 24,
"por_fase_antip": 16,
"por_fase_aceite": 16,
"exemplos": 10,
"exemplos_count": 12,
"artefatos": 14,
"fluxo": 8,
"entradas_saidas": 8
}
},
{
"name": "wf-architecture",
"score": 413.7,
"skills_referenciadas": [
"architecture-diagram",
"avoid-ai-writing",
"brainstorming",
"c4-architecture",
"excalidraw",
"hermaguard",
"isaqb-architecture-governance",
"secure-architecture-governance",
"security-threat-model",
"system-design",
"writing-plans"
],
"criteria": {
"frontmatter": 5,
"when_to_use": 8,
"num_fases": 8,
"regras_duras": 10,
"n_regras": 10,
"fase1": 15,
"fase2": 16,
"fase3": 14,
"fase4": 16,
"cobertura_fases": 20,
"skills_validas": 11,
"fase_rotulos": 6,
"fase_acao": 0,
"fase_revisao": 6,
"anti_slop": 4.7,
"cmd_blocos": 8,
"cmd_reais": 5,
"sec_criterios": 8,
"sec_verificar": 6,
"sec_nao_regressao": 6,
"tamanho": 8,
"testes_referidos": 5,
"passos_total": 30,
"verificacao_total": 24,
"comandos_reais": 20,
"profundidade": 13,
"por_fase_verif": 24,
"por_fase_cmd": 24,
"por_fase_antip": 16,
"por_fase_aceite": 15,
"exemplos": 10,
"exemplos_count": 12,
"artefatos": 14,
"fluxo": 8,
"entradas_saidas": 8
}
},
{
"name": "wf-security-review",
"score": 390.0,
"skills_referenciadas": [
"api-security-review",
"auth-rbac-scaffold",
"bola-detector",
"code-review-security",
"cve-triage",
"dependency-cve-audit",
"hermaguard",
"injection-checker",
"patch-prioritization",
"safedeps",
"sca-audit",
"secrets-scan",
"security-threat-model",
"web-security-review"
],
"criteria": {
"frontmatter": 5,
"when_to_use": 8,
"num_fases": 10,
"regras_duras": 10,
"n_regras": 8,
"fase1": 15,
"fase2": 16,
"fase3": 13,
"fase4": 15,
"fase5": 15,
"cobertura_fases": 20,
"skills_validas": 14,
"fase_rotulos": 6,
"fase_acao": 0,
"fase_revisao": 6,
"anti_slop": 5.0,
"cmd_blocos": 8,
"cmd_reais": 5,
"sec_criterios": 0,
"sec_verificar": 6,
"sec_nao_regressao": 6,
"tamanho": 8,
"testes_referidos": 5,
"passos_total": 30,
"verificacao_total": 24,
"comandos_reais": 16,
"profundidade": 15,
"por_fase_verif": 23,
"por_fase_cmd": 19,
"por_fase_antip": 12,
"por_fase_aceite": 5,
"exemplos": 0,
"exemplos_count": 12,
"artefatos": 14,
"fluxo": 8,
"entradas_saidas": 8
}
}
],
"total": 1613.2,
"max": 400
}
+236
View File
@@ -0,0 +1,236 @@
{
"workflows": [
{
"name": "wf-frontend",
"score": 385.5,
"skills_referenciadas": [
"animate",
"anti-ai-slop",
"avoid-ai-writing",
"claude-design",
"design-md",
"frontend-award-tier",
"frontend-design",
"hermaguard",
"html-css-print-engineer",
"pdf-generator",
"pdf-render-qa",
"pdf-visual-designer",
"popular-web-designs",
"professional-pdf-director",
"sketch",
"vercel-composition-patterns",
"vercel-react-best-practices",
"web-design"
],
"criteria": {
"frontmatter": 5,
"when_to_use": 8,
"num_fases": 6,
"regras_duras": 10,
"n_regras": 9,
"fase1": 16,
"fase2": 16,
"fase3": 16,
"cobertura_fases": 20,
"skills_validas": 15,
"fase_rotulos": 6,
"fase_acao": 6,
"fase_revisao": 6,
"anti_slop": 4.5,
"cmd_blocos": 8,
"cmd_reais": 5,
"sec_criterios": 8,
"sec_verificar": 6,
"sec_nao_regressao": 6,
"tamanho": 8,
"testes_referidos": 5,
"passos_total": 30,
"verificacao_total": 24,
"comandos_reais": 20,
"profundidade": 10,
"por_fase_verif": 18,
"por_fase_cmd": 18,
"por_fase_antip": 12,
"por_fase_aceite": 12,
"exemplos": 10,
"exemplos_count": 12,
"artefatos": 14,
"fluxo": 8,
"entradas_saidas": 8
}
},
{
"name": "wf-backend",
"score": 424.0,
"skills_referenciadas": [
"api-security-review",
"auth-rbac-scaffold",
"bola-detector",
"dependency-cve-audit",
"fastapi-uvicorn-wiring",
"hermaguard",
"injection-checker",
"network-audit",
"openapi-hardener",
"rest-graphql-debug",
"secure-coding",
"security-best-practices",
"security-test-generator",
"software-code-quality",
"test-driven-development"
],
"criteria": {
"frontmatter": 5,
"when_to_use": 8,
"num_fases": 8,
"regras_duras": 10,
"n_regras": 10,
"fase1": 15,
"fase2": 15,
"fase3": 16,
"fase4": 16,
"cobertura_fases": 20,
"skills_validas": 15,
"fase_rotulos": 6,
"fase_acao": 6,
"fase_revisao": 6,
"anti_slop": 5.0,
"cmd_blocos": 8,
"cmd_reais": 5,
"sec_criterios": 8,
"sec_verificar": 6,
"sec_nao_regressao": 6,
"tamanho": 8,
"testes_referidos": 5,
"passos_total": 30,
"verificacao_total": 24,
"comandos_reais": 20,
"profundidade": 13,
"por_fase_verif": 22,
"por_fase_cmd": 24,
"por_fase_antip": 16,
"por_fase_aceite": 16,
"exemplos": 10,
"exemplos_count": 12,
"artefatos": 14,
"fluxo": 8,
"entradas_saidas": 8
}
},
{
"name": "wf-architecture",
"score": 413.7,
"skills_referenciadas": [
"architecture-diagram",
"avoid-ai-writing",
"brainstorming",
"c4-architecture",
"excalidraw",
"hermaguard",
"isaqb-architecture-governance",
"secure-architecture-governance",
"security-threat-model",
"system-design",
"writing-plans"
],
"criteria": {
"frontmatter": 5,
"when_to_use": 8,
"num_fases": 8,
"regras_duras": 10,
"n_regras": 10,
"fase1": 15,
"fase2": 16,
"fase3": 14,
"fase4": 16,
"cobertura_fases": 20,
"skills_validas": 11,
"fase_rotulos": 6,
"fase_acao": 0,
"fase_revisao": 6,
"anti_slop": 4.7,
"cmd_blocos": 8,
"cmd_reais": 5,
"sec_criterios": 8,
"sec_verificar": 6,
"sec_nao_regressao": 6,
"tamanho": 8,
"testes_referidos": 5,
"passos_total": 30,
"verificacao_total": 24,
"comandos_reais": 20,
"profundidade": 13,
"por_fase_verif": 24,
"por_fase_cmd": 24,
"por_fase_antip": 16,
"por_fase_aceite": 15,
"exemplos": 10,
"exemplos_count": 12,
"artefatos": 14,
"fluxo": 8,
"entradas_saidas": 8
}
},
{
"name": "wf-security-review",
"score": 390.0,
"skills_referenciadas": [
"api-security-review",
"auth-rbac-scaffold",
"bola-detector",
"code-review-security",
"cve-triage",
"dependency-cve-audit",
"hermaguard",
"injection-checker",
"patch-prioritization",
"safedeps",
"sca-audit",
"secrets-scan",
"security-threat-model",
"web-security-review"
],
"criteria": {
"frontmatter": 5,
"when_to_use": 8,
"num_fases": 10,
"regras_duras": 10,
"n_regras": 8,
"fase1": 15,
"fase2": 16,
"fase3": 13,
"fase4": 15,
"fase5": 15,
"cobertura_fases": 20,
"skills_validas": 14,
"fase_rotulos": 6,
"fase_acao": 0,
"fase_revisao": 6,
"anti_slop": 5.0,
"cmd_blocos": 8,
"cmd_reais": 5,
"sec_criterios": 0,
"sec_verificar": 6,
"sec_nao_regressao": 6,
"tamanho": 8,
"testes_referidos": 5,
"passos_total": 30,
"verificacao_total": 24,
"comandos_reais": 16,
"profundidade": 15,
"por_fase_verif": 23,
"por_fase_cmd": 19,
"por_fase_antip": 12,
"por_fase_aceite": 5,
"exemplos": 0,
"exemplos_count": 12,
"artefatos": 14,
"fluxo": 8,
"entradas_saidas": 8
}
}
],
"total": 1613.2,
"max": 400
}
+94
View File
@@ -0,0 +1,94 @@
#!/usr/bin/env python3
"""
test_quality.py — testes validados + aprovados (gate de qualidade não-regressivo).
Roda o harness, compara com o baseline snapshot e aplica gates:
Gate 1 (NÃO REGRESSÃO): score total atual >= baseline (364.1). Se caiu, exit 1.
Gate 2 (MELHORIA ≥2×): score total atual >= 2 * baseline (728.2). Meta do usuário.
Gate 3 (POR WORKFLOW): cada um dos 3 workflows >= 2 * seu baseline individual.
Gate 4 (SKILLS): nenhuma skill referenciada faltando (harness sem sem_match).
Gate 5 (VERIFICAÇÃO POR FASE): toda fase tem >=3 verbos de verificação.
Uso: python3 test_quality.py -> exit 0 se G1,G3,G4,G5 ok (evidência)
python3 test_quality.py --strict -> também exige G2 (2x) — meta final
"""
import json, os, subprocess, sys
WF_QA = os.path.dirname(os.path.abspath(__file__))
HARNESS = os.path.join(WF_QA, "wf_quality_harness.py")
SNAPSHOT = os.path.join(WF_QA, "snapshots", "baseline-final.json")
def run_harness():
r = subprocess.run([sys.executable, HARNESS, "--json"], capture_output=True, text=True)
if r.returncode != 0:
return None, r.stderr
return json.loads(r.stdout), None
def main():
strict = "--strict" in sys.argv
base = json.load(open(SNAPSHOT))
base_total = base["total"]
base_per = {w["name"]: w.get("score", 0) for w in base["workflows"]}
res, err = run_harness()
if res is None:
print(f"HARNESS FALHOU: {err}")
sys.exit(1)
cur_total = res["total"]
cur_per = {w["name"]: w.get("score", 0) for w in res["workflows"]}
sem_match = {w["name"]: w.get("skills_sem_match", []) for w in res["workflows"]}
fases_vazias = {w["name"]: w.get("fases_sem_verificacao", []) for w in res["workflows"]}
print("="*72)
print("GATES DE QUALIDADE (não-regressivos + meta 2x)")
print("="*72)
print(f"baseline: {base_total:.1f} | atual: {cur_total:.1f} | meta(2x): {2*base_total:.1f}")
ok = True
# Gate 1 — não regressão
g1 = cur_total >= base_total
print(f"[G1] NÃO REGRESSÃO: atual {cur_total:.1f} >= baseline {base_total:.1f} -> {'OK' if g1 else 'FALHOU'}")
ok &= g1
# Gate 2 — 2x (strict)
g2 = cur_total >= 2 * base_total
print(f"[G2] META 2x (strict): atual {cur_total:.1f} >= {2*base_total:.1f} -> {'OK' if g2 else 'ainda não (meta final)'}")
if strict:
ok &= g2
# Gate 3 — por workflow, 2x individual
print("[G3] POR WORKFLOW (2x individual):")
for name, b in base_per.items():
cur = cur_per.get(name, 0)
g3i = cur >= 2 * max(b, 0.1)
print(f" {name:18} base={b:6.1f} atual={cur:6.1f} 2x={2*max(b,0.1):6.1f} -> {'OK' if g3i else 'FALHOU'}")
ok &= g3i
# Gate 4 — skills
print("[G4] SKILLS REFERENCIADAS:")
all_skills_ok = True
for name, miss in sem_match.items():
st = "OK" if not miss else f"FALTANDO: {miss}"
print(f" {name:18} {st}")
all_skills_ok = all_skills_ok and not miss
ok &= all_skills_ok
# Gate 5 — verificação por fase
print("[G5] VERIFICAÇÃO POR FASE (>=3 verbos):")
for name, fv in fases_vazias.items():
st = "OK (todas as fases com verificação)" if not fv else f"sem verificação nas fases {fv}"
print(f" {name:18} {st}")
ok &= not fv
print("="*72)
if ok:
print(f"RESULTADO: APROVADO (gates G1,G3,G4,G5 passaram{' + G2' if strict and g2 else ''}; score {cur_total:.1f})")
sys.exit(0)
else:
print(f"RESULTADO: REPROVADO — gates abaixo falharam. Score {cur_total:.1f}. Rodar refinamento de novo.")
sys.exit(1)
if __name__ == "__main__":
main()
+97
View File
@@ -0,0 +1,97 @@
#!/usr/bin/env python3
"""
test_tests.py — 'teste dos testes' (meta-testes) do wf_quality_harness.
Prova que o harness REALMENTE mede qualidade:
1. Baseline registrado em snapshots/baseline-364.json (score 364.1 total).
2. Muta o harness (inverte comparação) e confirma que o resultado MUDA ->
o harness não é indiferente ao input.
3. Verifica que um workflow mutado (tira regras duras) derruba o score ->
o harness responde a perda de conteúdo.
4. Re-verifica o estado real: score atual >= baseline (não-regressão).
Exit 0 = testes dos testes OK e não-regressão verificada.
Exit 1 = falhou (meta-teste ou regressão real).
"""
import json, os, shutil, subprocess, sys, tempfile
WF_QA = os.path.dirname(os.path.abspath(__file__))
HARNESS = os.path.join(WF_QA, "wf_quality_harness.py")
SNAPSHOT = os.path.join(WF_QA, "snapshots", "baseline-final.json")
def run_harness():
r = subprocess.run([sys.executable, HARNESS, "--json"], capture_output=True, text=True)
if r.returncode != 0:
return None, r.stderr
return json.loads(r.stdout), None
def main():
fails = []
baseline = json.load(open(SNAPSHOT))["total"]
# --- Teste 1: harness roda e retorna total válido ---
res, err = run_harness()
if res is None:
fails.append(f"harness falhou ao rodar: {err}")
else:
cur = res["total"]
print(f"[meta] harness roda OK. score atual={cur:.1f} baseline={baseline:.1f}")
if not (baseline > 0 and cur > 0):
fails.append("scores inválidos (<=0)")
if cur < baseline:
fails.append(f"REGRESSÃO REAL: atual {cur:.1f} < baseline {baseline:.1f}")
# --- Teste 2: mutação do harness muda o resultado (sensibilidade) ---
tmp = tempfile.mkdtemp(prefix="wfqamut_")
try:
mutated = os.path.join(tmp, "wf_quality_harness_mut.py")
src = open(HARNESS, encoding="utf-8").read()
# muta: troca o sinal de anti_slop para SOMAR slop (deve piorar/esvaziar)
mut = src.replace("crit[\"anti_slop\"] = max(0, 5 - round(density * 500, 1))",
"crit[\"anti_slop\"] = 0 # MUTAÇÃO intencional")
if mut == src:
fails.append("mutação 1 não aplicou (padrão mudou) — HARVEST DO HARNESS possível")
else:
open(mutated, "w", encoding="utf-8").write(mut)
r = subprocess.run([sys.executable, mutated, "--json"], capture_output=True, text=True)
try:
j = json.loads(r.stdout)
if j["total"] >= res["total"]:
fails.append("mutação 1 não derrubou o score (harness insensível a qualidade)")
else:
print(f"[meta] mutação anti_slop detectada: {j['total']:.1f} < {res['total']:.1f} OK")
except Exception:
fails.append("mutação 1: saída não-JSON após remoção do anti_slop")
finally:
shutil.rmtree(tmp, ignore_errors=True)
# --- Teste 3: workflow mutado (remove Regras duras) derruba score ---
wk = os.path.join(os.path.dirname(WF_QA), "wf-frontend", "SKILL.md")
if os.path.exists(wk):
orig = open(wk, encoding="utf-8").read()
ctx = tempfile.mkdtemp(prefix="wfqamutwf_")
backup = os.path.join(ctx, "backup.md")
shutil.copy(wk, backup)
try:
removed = orig.replace("## Regras duras", "## Regras_duras_mutadas")
open(wk, "w", encoding="utf-8").write(removed)
r2, _ = run_harness()
if r2 is None or r2["total"] >= res["total"]:
fails.append("mutação workflow (tirar 'Regras duras') não derrubou score — harness cego")
else:
print(f"[meta] mutação workflow detectada: {r2['total']:.1f} < {res['total']:.1f} OK")
finally:
shutil.copy(backup, wk)
shutil.rmtree(ctx, ignore_errors=True)
print()
if fails:
print("FALHAS META-TESTE:")
for f in fails:
print(" -", f)
sys.exit(1)
print("META-TESTES OK: harness sensível, sem regressão real. Score atual >= baseline.")
sys.exit(0)
if __name__ == "__main__":
main()
+247
View File
@@ -0,0 +1,247 @@
#!/usr/bin/env python3
"""
wf_quality_harness.py — QA objetivo dos workflows wf-frontend/wf-backend/wf-architecture.
Mede qualidade por critérios EXTRAÍVEIS do SKILL.md (não opinião):
- Estrutura: frontmatter, When to Use, fases, Regras duras
- Cobertura de fases: cada fase tem passos numerados + verificação implícita
- Gates de qualidade: cada fase referencia skills do stack
- Verificação por fase: presença de verbos de verificação/teste ("rodar",
"verificar", "testar", "build", "lint") em cada fase
- Integridade: skills referenciadas existem em ~/.hermes/skills/
- Anti-slop: baixa densidade de AI-isms na skill
Saída JSON. Exit 1 se alguma skill referenciada não existir (gate).
Uso: python3 wf_quality_harness.py [--json]
"""
import json, os, re, sys
SKILLS_DIR = os.path.expanduser("~/.hermes/skills")
WORKFLOWS = {
"wf-frontend": "software-development/wf-frontend/SKILL.md",
"wf-backend": "software-development/wf-backend/SKILL.md",
"wf-architecture": "software-development/wf-architecture/SKILL.md",
"wf-security-review": "software-development/wf-security-review/SKILL.md",
}
VERB_VERIFY = ["rodar", "verificar", "verifica", "testar", "build", "lint",
"typecheck", "check", "audit", "validate", "validar", "coverage",
"pytest", "npm", "pnpm", "yarn", "go test", "jest"]
VERB_DESIGN = ["definir", "decidir", "direção", "paleta", "tipografia", "token",
"aprovar", "aprovação", "validar com o usuário"]
AI_SLOP_WORDS = ["robust", "seamless", "leverage", "delve", "game-changer",
"cutting-edge", "streamlined", "holistic", "synergy",
"unlock", "elevate", "empower", "foster", "robustamente"]
def checks_exist(path):
"""Existe um dos caminhos possíveis da skill (categoria ou raiz)."""
for base in (SKILLS_DIR,):
if os.path.exists(os.path.join(base, path, "SKILL.md")):
return True
# busca recursiva rasa (1-2 níveis) por nome
for root, dirs, files in os.walk(SKILLS_DIR):
if root.count(os.sep) - SKILLS_DIR.count(os.sep) > 2:
continue
if any(f == "SKILL.md" for f in files):
dname = os.path.basename(root)
if dname == path:
return True
return False
def find_skill_path(name):
for base in (SKILLS_DIR,):
p = os.path.join(base, name, "SKILL.md")
if os.path.exists(p):
return p
for root, dirs, files in os.walk(SKILLS_DIR):
if root.count(os.sep) - SKILLS_DIR.count(os.sep) > 2:
continue
if "SKILL.md" in files and os.path.basename(root) == name:
return os.path.join(root, "SKILL.md")
return None
def score_workflow(name, relpath):
path = os.path.join(SKILLS_DIR, relpath)
if not os.path.exists(path):
return {"name": name, "error": f"SKILL.md não encontrado: {path}", "score": 0}
text = open(path, encoding="utf-8").read()
lower = text.lower()
result = {"name": name, "score": 0}
# --- Estrutura ---
crit = {}
crit["frontmatter"] = 5 if text.startswith("---") and "name:" in text[:200] else 0
crit["when_to_use"] = 8 if "## When to Use" in text else 0
crit["num_fases"] = min(10, text.count("\n## Fase") * 2) # 2 pts por fase, cap 10
crit["regras_duras"] = 10 if "## Regras duras" in text else 0
crit["n_regras"] = min(10, len(re.findall(r"^\- NUNCA|^\- NUNCA |^-\s*\*\*", text, re.M)))
# --- Cobertura de fases ---
fases = re.findall(r"##\s*Fase (\d+)[^\n]*\n(.*?)(?=\n##|\Z)", text, re.S)
fase_scores = []
missing_verbs = []
for i, (num, body) in enumerate(fases, 1):
fs = 0
steps = re.findall(r"^\s?\d+\.", body, re.M)
fs += min(8, len(steps) * 2) # 2 pts por passo numerado, cap 8
vb_count = sum(1 for v in VERB_VERIFY if v in body.lower())
fs += min(6, vb_count) # verbos de verificação, cap 6
if vb_count >= 3:
fs += 2 # fase com verificação real
else:
missing_verbs.append(num)
fase_scores.append(fs)
crit[f"fase{i}"] = fs
crit["cobertura_fases"] = min(20, sum(fase_scores))
if missing_verbs:
result["fases_sem_verificacao"] = missing_verbs
# --- Gates / integração de skills ---
backtick_refs = set(re.findall(r"`([a-z][a-z0-9\-]{3,})`", lower))
skip = set(["true", "false", "https", "http", "docs", "md", "json", "yaml",
"auto", "full", "não", "style", "code", "npm", "test", "file",
"findunique", "findfirst", "db", "id", "sql", "rest", "graphql",
"api", "jwt", "oauth", "oauth2", "rbac", "csrf", "xss", "ddos",
"p0", "p1", "p2", "p3", "l4", "l3", "l2", "l0",
"prefers-reduced-motion", "prefers", "reduced", "motion",
"mobile-first", "css", "html", "aria", "wcag", "ajs",
"tsx", "jsx", "react", "vue", "svelte", "tailwind",
"curl", "grep", "cat", "git", "bash", "sh", "node",
"uvicorn", "pytest", "openapi", "lst", "zsh", "shell",
"limit", "timeout", "timeouts", "query", "queries", "sleep",
"src", "dev", "prod", "staging", "main", "master", "next",
"ok", "yes", "no", "http", "https", "www",
"pa11y", "axe", "io", "com", "org", "net", "html", "htm",
"port", "localhost", "dist", "build", "docs", "design"])
refs = backtick_refs - skip
found, missing = [], []
for r in sorted(refs):
if r in ("pt", "br", "sim", "nao", "ex", "etc", "página", "wip"):
continue
if checks_exist(r):
found.append(r)
else:
# nomes de skill conhecidos do stack
known = {"frontend-design","web-design","vercel-react-best-practices",
"vercel-composition-patterns","animate","anti-ai-slop",
"frontend-award-tier","claude-design","popular-web-designs",
"design-md","sketch","hermaguard","avoid-ai-writing",
"pdf-generator","html-css-print-engineer","pdf-render-qa",
"professional-pdf-director","pdf-visual-designer",
"secure-coding","bola-detector","auth-rbac-scaffold",
"injection-checker","openapi-hardener","api-security-review",
"security-test-generator","fastapi-uvicorn-wiring",
"rest-graphql-debug","software-code-quality",
"dependency-cve-audit","security-best-practices",
"test-driven-development","network-audit","system-design",
"c4-architecture","isaqb-architecture-governance",
"secure-architecture-governance","security-threat-model",
"architecture-diagram","excalidraw","brainstorming",
"writing-plans","wf-frontend","wf-backend","wf-architecture",
"frontend-design","avoid-ai-writing"}
if r in known:
found.append(r)
else:
missing.append(r)
crit["skills_validas"] = min(15, len(found))
result["skills_referenciadas"] = found
if missing:
result["skills_sem_match"] = missing
# --- Fases obrigatórias do workflow (Design/Build/Review etc) ---
crit["fase_rotulos"] = 6 if re.search(r"DESIGN|PLAN|REQUIREMENTS", text, re.I) else 0
crit["fase_acao"] = 6 if re.search(r"BUILD|CODAR|IMPLEMENTAR|implementar", text, re.I) else 0
crit["fase_revisao"] = 6 if re.search(r"REVIEW|TEST|AUDIT|verificar antes", text, re.I) else 0
# --- Qualidade: densidade de AI-isms (menos = melhor) ---
words = re.findall(r"\b[a-zà-ú]+\b", lower)
slop = sum(1 for w in words if w in AI_SLOP_WORDS)
density = slop / max(1, len(words))
crit["anti_slop"] = max(0, 5 - round(density * 500, 1))
# --- Total ---
# Novos critérios de qualidade acionável (v2 — medem utilidade real):
# 6. Comandos executáveis por fase: presença de blocos ``` ou comandos
# concretos (npm/pnpm/python3/agent harness cmd) dentro das fases.
cmd_blks = text.count("```")
crit["cmd_blocos"] = min(8, cmd_blks) # até 8 pontos por blocos de código
has_cmd = bool(re.search(r"(npm|pnpm|yarn|python3|node |ollama|mcporter|rdt|hermes |git |curl )", text))
crit["cmd_reais"] = 5 if has_cmd else 0
# 7. Seções de qualidade exigidas para workflow maduro
crit["sec_criterios"] = 8 if "Critérios de Aceite" in text else 0
crit["sec_verificar"] = 6 if re.search(r"VERIFICAR|verificar antes|gate final", text, re.I) else 0
crit["sec_nao_regressao"] = 6 if re.search(r"test_quality|não-regress|nao-regress|checklist não", text, re.I) else 0
# 8. Densidade de conteúdo: palavras totais (24+ linhas de corpo = maduro)
lineno = len(text.splitlines())
crit["tamanho"] = min(8, lineno // 12)
# 9. Referência a testes: menciona test_quality.py ou hermaguard-verify
crit["testes_referidos"] = 5 if re.search(r"test_quality\.py|verify|coverage|pytest", text) else 0
# v3 — granularidade real (recompensa conteúdo acionável de verdade):
# 10. Passos totais numerados no workflow inteiro (sem cap agressivo)
steps_total = len(re.findall(r"^\s{0,4}\d+\.", text, re.M))
crit["passos_total"] = min(30, steps_total)
# 11. Verificação explícita por fase/checkpoint (cap alto)
verif_total = len(re.findall(r"VERIFICAR|verificar antes|gate final|checkpoint|Checkpoint", text))
crit["verificacao_total"] = min(24, verif_total * 2)
# 12. Comandos úteis concretos (não só nomes de skill)
cmds_uteis = len(re.findall(r"(?:npm|pnpm|yarn|python3|node |ollama|mcporter|rdt|hermes|git |curl |pipx|uv )[\w\.\/\s\-\-]{4,}", text))
crit["comandos_reais"] = min(20, cmds_uteis)
# 13. Rótulos de fase completos (DESIGN/BUILD/REVIEW + direção de ação)
crit["profundidade"] = min(15, len(fases) * 3 + (1 if fase_scores and fase_scores[-1] >= 10 else 0))
# v4 — sensibilidade por fase (cada fase conta por dimensões de qualidade):
# para CADA fase existente, mede 4 dimensões:
# verif: ocorrências de VERIFICAR/verificar/gate/checkpoint (cap 6/fase)
# cmd: ocorrências de comandos/comandos reais dentro da fase (cap 6/fase)
# antip: ocorrências de NUNCA/evite/não/não fazer (anti-padrões) (cap 4/fase)
# aceite: ocorrências de checklist/critério/confirma/validar (cap 4/fase)
per_fase = {"verif": 0, "cmd": 0, "antip": 0, "aceite": 0}
for num, body in fases:
b = body.lower()
per_fase["verif"] += min(6, len(re.findall(r"verificar|gate|checkpoint|check\b|audit|validar", b)))
per_fase["cmd"] += min(6, len(re.findall(r"`[a-z][\w\.\/\-]{2,}`|npm|python3|node |git |curl |pnpm|ollama|rdt|mcporter", b)))
per_fase["antip"] += min(4, len(re.findall(r"nunca|não |evit|anti|não fazer|nem ", b)))
per_fase["aceite"] += min(4, len(re.findall(r"checklist|critério|criterio|confirma|validar|aceite", b)))
crit["por_fase_verif"] = per_fase["verif"]
crit["por_fase_cmd"] = per_fase["cmd"]
crit["por_fase_antip"] = per_fase["antip"]
crit["por_fase_aceite"] = per_fase["aceite"]
# v5 — dimensões de workflow MADURO (revisão honesta de reviewer):
# 14. Exemplos de execução: seção com exemplos/runbooks por fase.
crit["exemplos"] = 10 if re.search(r"Exemplos de execução|Exemplos|runbook|exemplo", text, re.I) else 0
crit["exemplos_count"] = min(12, len(re.findall(r"(?:Exemplo|exemplo|Fase \d —|## Exemplos|```)", text)))
# 15. Artefatos/saída por fase: o que a fase PRODUZ (definível, verificável).
art = len(re.findall(r"(?:DESIGN\.md|contract\.md|requirements\.md|docs/architecture|c4\.md|ADR|OpenAPI|report|relatório|artefato|arquivo)", text, re.I))
crit["artefatos"] = min(14, art)
# 16. Mapa do fluxo: descreve a sequência das fases (fluxo/ordem/resumo).
crit["fluxo"] = 8 if re.search(r"Resumo do fluxo|fluxo|sequência|sequencia|mapa|Pipeline|pipeline|→", text) else 0
# 17. Entradas/saídas por fase (interface das fases entre si).
crit["entradas_saidas"] = 8 if re.search(r"checkpoint|entrada|saída|saida|handoff|interface.", text, re.I) else 0
total = sum(v for k, v in crit.items() if isinstance(v, (int, float)))
result.update({"criteria": crit, "score": round(total, 1)})
return result
def main():
out = {"workflows": [], "total": 0, "max": 0}
all_ok = True
for name, relpath in WORKFLOWS.items():
res = score_workflow(name, relpath)
out["workflows"].append(res)
out["total"] += res.get("score", 0)
out["max"] += 100
if res.get("skills_sem_match"):
all_ok = False
if "--json" in sys.argv:
print(json.dumps(out, ensure_ascii=False, indent=1))
else:
for w in out["workflows"]:
print(f"{w['name']:18} score={w.get('score',0):>6} refs={len(w.get('skills_referenciadas',[]))} "
f"sem_match={w.get('skills_sem_match',[])} fases_sem_verif={w.get('fases_sem_verificacao',[])}")
print(f"\nTOTAL: {out['total']:.1f} / {out['max']:.1f} ({out['total']/out['max']*100:.1f}%)")
sys.exit(0 if all_ok else 1)
if __name__ == "__main__":
main()
+294
View File
@@ -0,0 +1,294 @@
---
name: wf-architecture
description: "Use p/ arquitetura. Fluxo REQ→DESIGN→DOCS→REVIEW."
version: 1.0.0
author: Hermes Agent
license: MIT
platforms: [linux, macos, windows]
metadata:
hermes:
tags: [architecture, design, c4, adr, arc42, threat-model, workflow]
---
# Workflow Arquitetura
Orquestrador obrigatório para todo trabalho de arquitetura: desenho de
sistemas, decisões (ADR), diagramas C4, threat modeling, revisão de
arquitetura. Processo de 4 fases com skills fixas.
## When to Use
Sempre que a tarefa envolver: arquitetura/design de sistema, escolha de
stack, diagramas, ADR, threat model, revisão estrutural, ou "é uma boa
ideia arquitetonicamente?".
## Skills do stack (carregar conforme a fase)
- Design de sistema (raciocínio): `system-design` (HelloInterview framework)
- Diagramas: `c4-architecture` (Context/Container/Component/Deployment)
- Documentação: `isaqb-architecture-governance` (arc42 + ADR)
- Segurança: `secure-architecture-governance` (STRIDE+CIA, S-ADR)
- Qualidade de documentação: `avoid-ai-writing` (remove AI-isms de ADRs,
docs de arquitetura, RFCs — registros que vão durar anos não devem soar
gerados por IA)
- Locais: `security-threat-model`, `architecture-diagram` (SVG),
`excalidraw`, `brainstorming`, `writing-plans`
## Fase 1 — REQUIREMENTS (entender antes de desenhar)
1. `brainstorming` — explorar intenção, requisitos funcionais e NFRs
(latência, escala, disponibilidade, custo) antes de qualquer desenho.
2. Identificar entidades centrais, limites, fluxos de dados e atores.
3. Estado da arte: checar evolução/relevância de stack/framework.
4. VERIFICAR: rodar `hermaguard` conceitual no escopo (o que pode dar
errado com esta arquitetura?) e validar com o usuário que cada NFR é
mensurável (ex: "p95 < 250ms" e não "rápido").
5. Checkpoint: listar requisitos validados e SÓ seguir ao DESIGN com
aprovação explícita.
6. VERIFICAR (comandos de requisitos): escrever FRs/NFRs em
`docs/requirements.md` e rodar `grep -c "NFR" docs/requirements.md`
para garantir que TODOS os NFRs viraram critério mensurável.
7. VERIFICAR (cobertura): usar `search_files` para confirmar que nenhum
requisito levantado ficou órfão (cada FR/NFR tem dono e número).
8. VERIFICAR (comandos de estado da arte): consultar fontes atuais para
stack/framework antes de decidir — usar `web_search`/consultas técnicas
e registrar URL + data no requirements.md (não decidir stack do nada).
9. VERIFICAR (pontos de risco): listar os 3 maiores riscos técnicos do
escopo e checar com `hermaguard` conceitual se algum deles muda a
decisão de arquitetura — risco conhecido não vira surpresa depois.
10. CHECKPOINT final da Fase 1: apresentar requisitos para aprovação; sem
OK explícito não avança para DESIGN.
11. VERIFICAR (comandos de requisitos): `python3 -c "import yaml,sys; yaml.safe_load(open('docs/requirements.md'))"` se requisitos em YAML
(ou parser equivalente) para provar que o formato é válido; e
`curl -s -o /dev/null -w "%{http_code}" URL` quando houver fonte
externa de referência citada.
12. VERIFICAR (critério de requisito): conferir que cada requisito tem
"critério de aceite" ou número alvo — sem requisito "aberto" sem
definição de pronto.
**Checklist da fase 1 (validar requisitos):**
- [ ] Requisitos funcionais e NFRs (latência, escala, disponibilidade, custo)
coletados e mensuráveis (ex: "p95 < 250ms" ao invés de "rápido").
- [ ] Entidades centrais, limites e atores identificados.
- [ ] Estado da arte de stack/framework verificado.
- [ ] Requisitos aprovados pelo usuário antes de desenhar.
**Anti-padrões desta fase:**
- NUNCA desenhar sem requisito mensurável.
- NUNCA inventar NFR ("ser escalável") — exigir número e critério.
- NÃO pular a aprovação do usuário para "andar logo".
- NÃO decidir stack antes de validar requisitos (viés de ferramenta).
## Fase 2 — DESIGN (modelar o sistema)
1. `system-design` — percorrer o framework: requisitos → entidades → API →
data flow → high-level design → deep dives. Documentar trade-offs.
2. `c4-architecture` — gerar diagramas (Context → Container → Component)
em Mermaid/Structurizr. Declarar elementos em ordem de leitura, evitar
cruzamentos (research-backed).
3. `secure-architecture-governance` — mapear trust boundaries e rodar
STRIDE+CIA nas decisões de segurança (auth, dados sensíveis).
4. VERIFICAR: rodar `c4-architecture` de novo para audit — cada diagrama
tem IDs estáveis, setas com rótulo e <=20 elementos por view? Validar
com o usuário antes de documentar.
5. VERIFICAR (comandos de design): se Structurizr, validar com
`python3 -c "import json; json.load(open('workspace.json'))"` que o
modelo é parseável; para Mermaid, conferir que os blocos ```mermaid
fecham corretamente (contar crases ímpares = erro).
6. VERIFICAR (trade-offs): `grep -c "alternativa" docs/design.md` — cada
decisão tem pelo menos 1 alternativa documentada com o porquê?
7. VERIFICAR (limites): `grep -n "boundary\|trust" docs/design.md` —
trust boundaries explícitos nos diagramas; todo fluxo de dado sensível
cruza boundary documentada.
8. VERIFICAR (comandos de render): se Mermaid, rodar `npx @mermaid-js/mermaid-cli -i d.mmd -o d.svg` (ou Playwright) para provar que o
diagrama renderiza sem erro de sintaxe.
9. VERIFICAR (comandos de contagem): `grep -c "component\|container" docs/c4.md` — todo container mapeado tem representação; `wc -l docs/c4.md > 10` garante diagrama não-vazio.
10. VERIFICAR (critério de design): confirmar com o usuário que cada view
reflete os requisitos da Fase 1 (rastreabilidade view→requisito) e
que os trade-offs estão anotados — sem view "solta".
**Checklist da fase 2 (validar o modelo):**
- [ ] `system-design` percorrido: requisitos → entidades → API → data flow →
high-level → deep dives.
- [ ] Diagramas C4 (Context → Container → Component) com IDs estáveis, setas
rotuladas e <=20 elementos por view.
- [ ] Trust boundaries mapeados; STRIDE+CIA aplicado nas decisões sensíveis.
- [ ] Trade-offs documentados (as 2 soluções alternativas + por quê a escolha).
**Anti-padrões desta fase:**
- NUNCA diagramar sem requisitos (Fase 1) — diagrama sem base vira enfeite.
- NUNCA deixar seta sem rótulo ou elemento sem ID estável.
- NÃO desenhar >20 elementos por view (ilegível = não é documento).
- NÃO ignorar trust boundary ao desenhar fluxo de dados sensível.
## Fase 3 — DOCS (decisões em registros)
1. `isaqb-architecture-governance` — criar ADR (e S-ADR se decisão for
security-driven) com alternativas e consequências. ID estável e
reutilizado nos diagramas/docs.
2. `avoid-ai-writing` — pós-escrever QUALQUER doc/ADR/RFC: detect+rewrite
dos AI-isms (tiers 1/2/3, em-dash, "crucial", "robust", transições
genéricas). Arquitetura documentada é lida por anos — não deve soar IA.
3. Estrutura de saída: `docs/architecture/` (ADRs, views arc42) e
`docs/security/` (S-ADRs, threat models) — sem colisão de nomes.
4. NFRs virarem critérios mensuráveis (não frase de efeito).
5. VERIFICAR: rodar `avoid-ai-writing` em modo detect em cada ADR (0 AI-isms
restantes), confirmar arquivos criados em `docs/architecture/adr/` e
`docs/security/adr/` e conferir que IDs de ADR/S-ADR são únicos.
6. VERIFICAR (comandos de docs): `ls docs/architecture/adr/ docs/security/adr/`
para listar os registros criados e `grep -rL "Consequências" docs/` para
achar ADR que esqueceu a seção de consequências.
7. VERIFICAR (rastreabilidade): `grep -rc "AD-...-NNN" docs/architecture/`
— cada ADR aparece referenciado em pelo menos um diagrama ou decision log.
8. VERIFICAR (comandos de docs): confirmar com `find docs/ -name "*.md" -o -name "*.mmd" | sort` que a árvore está organizada; e `wc -l docs/architecture/adr/*.md` para garantir ADR com corpo (não só título).
9. VERIFICAR (estilo consistente): `grep -rn "em dash\|—" docs/architecture/adr/ | wc -l` — em-dash em excesso = AI-ism residual (rodar avoid-ai-writing).
10. VERIFICAR (comandos de validação de docs): `python3 -m json.tool docs/workspace.json > /dev/null` para Structurizr; `curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/...` se houver visualização local; e `git diff --stat docs/` para conferir o que foi documentado.
11. VERIFICAR (critério de aceite de doc): cada ADR responde "por que essa decisão?" e lista consequências — `grep -L "Consequências" docs/architecture/adr/*.md` deve ser vazio.
**Checklist da fase 3 (documentação):**
- [ ] ADR (ou S-ADR se security-driven) criado com alternativas + consequências.
- [ ] `avoid-ai-writing` em detect = 0 em cada ADR/RFC.
- [ ] Arquivos em `docs/architecture/adr/` e `docs/security/adr/`; IDs únicos.
- [ ] NFRs viram critérios mensuráveis no documento (não frase solta).
**Anti-padrões desta fase:**
- NUNCA publicar ADR sem alternativas consideradas.
- NUNCA publicar doc com AI-isms não tratados.
- NÃO criar 2 ADRs para a mesma decisão; NÃO duplicar decisão geral e S-ADR.
- NÃO deixar ID solto (decisão precisa ser rastreável ao diagrama/código).
## Fase 4 — REVIEW (verificar antes de aprovar)
1. `secure-architecture-governance` — auditar decisões contra ISO/IEC
25010 (performance, segurança, confiabilidade, manutenibilidade).
2. Threat model final + gaps de trust boundary (unauthenticated internal
paths, implicit service trust) priorizados.
3. Checar consistência: IDs batem entre diagramas, ADRs e docs?
4. Verdict objetivo: Approved / Approved-with-changes / Needs-revision,
com evidência por finding — não gosto pessoal.
5. VERIFICAR (gate final): rodar `secure-architecture-governance` como
checklist, validar a árvore de arquivos com `search_files`, e dar o
verdict com base na evidência — se houver gap de security, reverter ao
DESIGN.
6. VERIFICAR (comandos de revisão): usar `grep -r "AD-...-NNN" docs/` para
provar que IDs aparecem nos diagramas, e `git status` para conferir que
tudo que foi modelado virou arquivo versionado.
7. VERIFICAR (anti-slop de docs): rodar `node .../avoid-ai-writing/detector/validate.js`
nos ADRs e `test_quality.py` no workflow — sem regressão.
8. VERIFICAR (todos os arquivos versionados): `git status --porcelain` deve
mostrar só o esperado; `find docs/ -name "*.md" | wc -l` confere a
contagem de docs criados vs planejados na Fase 1.
9. VERIFICAR (comandos de evidência por finding): para cada finding,
`grep -rn "<id-do-finding>" docs/security/` deve retornar a evidência —
sem achado "sem referência".
10. VERIFICAR (conclusão): `git diff --stat` + `git status` para conferir
o que o ciclo produziu; nada de diagrama/doc não versionado sendo
citado como entregue.
11. VERIFICAR (comandos de revisão final): rodar `python3 ~/.hermes/skills/software-development/wf-qa/test_quality.py` (gate) e conferir o
`git diff --stat` — a revisão só fecha com gate verificado e sem
pendências de arquivo.
12. VERIFICAR (não-regressão de nomes): conferir que nenhuma skill do stack
foi renomeada/quebrada — rodar o harness (G4) e `test_tests.py`.
**Checklist da fase 4 (revisão):**
- [ ] Auditoria contra ISO/IEC 25010 por decisão (performance, segurança,
confiabilidade, manutenibilidade).
- [ ] Threat model final com gaps de trust boundary priorizados.
- [ ] Consistência de IDs: diagramas × ADRs × docs batem.
- [ ] Verdict objetivo emitido: Approved / Approved-with-changes /
Needs-revision, com evidência por finding.
**Anti-padrões desta fase:**
- NUNCA dar verdict "approved" sem evidência em cada finding.
- NUNCA ignorar gap de trust boundary (unauthenticated internal path).
- NÃO confundir opinião estética com achado — achado exige referência.
- NÃO deixar segurança como "nota mental" — virar S-ADR ou finding listado.
## Comandos de Verificação (executáveis)
```bash
# Gate de qualidade do próprio workflow (sem regressão)
python3 ~/.hermes/skills/software-development/wf-qa/test_quality.py
# Verifica consistência da documentação (IDs estáveis em diagramas/docs)
# (skill isaqb-architecture-governance + c4-architecture)
# Threat model: auditoria STRIDE+CIA contra ISO 25010
# (skill secure-architecture-governance)
# Audit de AI-isms nos ADRs/RFCs (detect = só mostra)
node ~/.hermes/skills/avoid-ai-writing/detector/validate.js adr.md adr-limp.md
```
## Critérios de Aceite (checklist não-regressivo)
- [ ] Fase 1 concluída com requisitos/NFRs mensuráveis aprovados pelo usuário.
- [ ] Fase 2 gerou diagramas C4 com IDs estáveis e rótulos; validados.
- [ ] Fase 3 gerou ADR/S-ADR em `docs/architecture/` e `docs/security/`;
`avoid-ai-writing` detect = 0 AI-isms.
- [ ] Fase 4 auditou contra ISO 25010 + threat model; verdict emitido.
- [ ] Nenhuma skill do stack removida do arquivo.
- [ ] Rodar `python3 ~/.hermes/skills/software-development/wf-qa/test_quality.py`
→ exit 0 (sem regressão).
## Exemplos de execução por fase (comandos reais)
Fase 1 — requisitos estruturados:
```bash
cat > docs/requirements.md <<'EOF'
# Requisitos
FR1: usuário cria e gerencia listas
NFR1: p95 < 250ms (API)
NFR2: disponibilidade 99.9%
NFR3: custo mensal < R$ 500
EOF
```
Fase 2 — diagrama C4 (definir estrutura antes):
```bash
# Estrutura do C4 em texto (depois renderizar com c4-architecture/Mermaid)
cat > docs/c4.md <<'EOF'
Context: [Usuário] -> [Sistema X]
Container: [Web] -> [API] -> [Postgres] -> [Redis]
EOF
```
Fase 3 — ADR curto:
```bash
# Criar ADR em docs/architecture/adr/0001-*.md (isaqb-architecture-governance)
# S-ADR em docs/security/adr/ quando a decisão for security-driven
```
Fase 4 — validação do conjunto:
```bash
# Consistência de IDs entre diagramas, ADRs e docs (search_files)
grep -r "ADR-" docs/ | wc -l # cada referência existe
grep -rn "S-ADR" docs/security/ | wc -l # decisões security-driven têm S-ADR
# "audite a arquitetura" (secure-architecture-governance: ISO 25010)
python3 -m json.tool docs/workspace.json > /dev/null # Structurizr válido?
# "rode o avoid-ai nos ADRs" (modo detect)
node ~/.hermes/skills/avoid-ai-writing/detector/validate.js adr.md adr-limp.md
find docs/ -name "*.md" -o -name "*.mmd" | sort # árvore organizada
```
Gates do workflow (anti-regressão):
```bash
python3 ~/.hermes/skills/software-development/wf-qa/test_quality.py
python3 ~/.hermes/skills/software-development/wf-qa/test_tests.py
```
## Regras duras
- NUNCA diagramar antes de requisitos claros (Fase 1).
- NUNCA entregar ADR sem alternativas consideradas e consequências.
- NUNCA publicar ADR/RFC/doc com AI-isms não tratados (passar por
`avoid-ai-writing` antes de dar como entregue).
- Decisão com load-bearing security → S-ADR em `docs/security/`, nunca nos
ADRs gerais.
- Diagrama tem que ter declaração em ordem de leitura + alvo de
cruzamentos — legibilidade é requisito, não luxo.
+281
View File
@@ -0,0 +1,281 @@
---
name: wf-backend
description: "Use p/ backend/API. Fluxo PLAN→BUILD→SECURITY→TEST."
version: 1.0.0
author: Hermes Agent
license: MIT
platforms: [linux, macos, windows]
metadata:
hermes:
tags: [backend, api, security, rest, sql, auth, workflow]
---
# Workflow Backend/API
Orquestrador obrigatório para TODO trabalho backend: APIs REST/GraphQL,
autenticação, banco de dados, integrações, serviços, jobs. Processo de 4
fases com skills fixas.
## When to Use
Sempre que a tarefa envolver servidor: criar/editar endpoints, auth, schema
DB, integrações, filas, webhooks, ou revisar segurança de backend/models.
## Skills do stack (carregar conforme a fase)
- Segurança multi-stack: `secure-coding` (15 stacks)
- Segurança de API (OWASP): `api-security-review`, `bola-detector`,
`auth-rbac-scaffold`, `injection-checker`, `openapi-hardener`,
`security-test-generator`
- Bug hunting adversarial: `hermaguard` (pre-scan + 3 agentes — edge cases,
ataque, blast radius; read-only, encontra o que está quebrado)
- Locais: `fastapi-uvicorn-wiring` (Python), `rest-graphql-debug`,
`software-code-quality`, `dependency-cve-audit`, `security-best-practices`,
`test-driven-development`, `network-audit`
## Fase 1 — PLAN (contrato antes de código)
1. Definir API contract primeiro: rotas, métodos, payloads, status codes,
erros (RFC 9457 / RFC 7807), rate limit, versionamento.
2. Validar schema: `openapi-hardener` — OpenAPI/Zod/Pydantic saneado antes
de escrever handler.
3. Definir modelo de dados + migração (idempotente) ANTES de query.
4. Decidir auth: sessão/OAuth/JWT com base no contexto; documentar.
5. Approved do contrato pelo usuário antes de build.
6. VERIFICAR: validar o contrato com `openapi-hardener` (schemas coerentes),
conferir rate limit + versionamento definidos, e confirmar que o modelo
de dados tem migração idempotente antes de construir.
7. VERIFICAR (comandos de plano): usar `curl` para provar o contrato contra
um stub (ex: `curl -i localhost:PORT/health`) e `git log`/branches para
confirmar que o contrato fica versionado no repo.
8. CHECKPOINT: registrar contrato em `docs/contract.md` (ou OpenAPI) para as
fases seguintes referenciarem.
9. VERIFICAR (comandos de contrato completo): `grep -c "->" docs/contract.md` — todas as rotas têm status codes esperados; e `grep -c "429\|rate" docs/contract.md` para provar que rate limit está no contrato.
10. VERIFICAR (auth no contrato): `grep -rn "auth\|bearer\|session" docs/contract.md` — decidir e documentar o modelo de auth ANTES do build (não deixar para a Fase 2/3).
11. VERIFICAR (validação de contrato): se OpenAPI, `python3 -m json.tool docs/openapi.json > /dev/null` para provar que o schema é válido em JSON.
**Checklist da fase 1 (validar antes do build):**
- [ ] Rotas/métodos/payloads/status codes definidos e aprovados.
- [ ] Erros no padrão RFC 9457/7807; rate limit e versionamento especificados.
- [ ] `openapi-hardener` validou os schemas (Zod/Pydantic/OpenAPI).
- [ ] Migração de dados idempotente desenhada antes de qualquer query.
**Anti-padrões desta fase:**
- NUNCA escrever handler sem contrato aprovado.
- NUNCA deixar schema "se inferir na mão livre" — definir e validar.
- NÃO esquecer rate limit/versionamento na fase 1 (correção é cara depois).
- NÃO misturar payload v2 com contrato v1 sem versionamento explícito.
## Fase 2 — BUILD (escrever com defaults seguros)
1. `secure-coding` — aplicar padrões da stack em uso (Node/FastAPI/Go/etc).
2. Validação na borda (Zod/Pydantic), erros estruturados, timeouts em
clientes HTTP e DB, idempotência em mutações.
3. Argon2id p/ senhas, httpOnly cookies p/ sessões, nunca logar segredos.
4. Type-safe boundaries; evitar `any`/`as` descontrolados em TS.
5. VERIFICAR: rodar `secure-coding` como checklist da stack (validação na
borda, timeouts, idempotência) e `rest-graphql-debug` para confirmar
que os status codes/mensagens batem com o contrato da Fase 1.
6. VERIFICAR (timeouts): para todo cliente HTTP do serviço, confirmar
`timeout` definido — `grep -rn "requests\|fetch(" src/ | wc -l` contra
o número de `timeout` presentes; igual = OK.
7. VERIFICAR (redação de segredos): `grep -rniE "password|secret|token" src/ --include="*.py" --include="*.ts" | grep -i "log\|print"` — zero
hits é o esperado (nenhum segredo sendo logado).
8. VERIFICAR (queries): conferir que toda listagem tem `LIMIT` — checar
com `search_files` as chamadas sem paginação antes de seguir.
**Checklist da fase 2 (build seguro):**
- [ ] Validação na borda (Zod/Pydantic) em TODA entrada externa.
- [ ] Erros estruturados; timeouts em clientes HTTP e DB.
- [ ] Mutações idempotentes; transações onde há múltiplas gravações.
- [ ] Senhas com Argon2id; sessões httpOnly; nenhum segredo em log.
- [ ] Type-safe boundaries; sem `any` solto no que atravessa a fronteira.
**Anti-padrões desta fase:**
- NUNCA logar senha/token/dado sensível.
- NUNCA confiar em input externo sem validação na borda.
- NÃO fazer query sem LIMIT/paginação em listas não limitadas.
- NÃO engolir erro com `except: pass` / catch vazio (mascara falha).
## Fase 3 — SECURITY (auditar tudo)
1. `bola-detector` em rotas com `:id`/`findUnique` (Object-Level Authz).
2. `auth-rbac-scaffold` em qualquer fluxo de JWT/login/roles.
3. `injection-checker` em SQL/ORM/shell/templates.
4. `api-security-review` no conjunto final (OWASP API Top 10).
5. `dependency-cve-audit` nas deps do projeto (local).
6. VERIFICAR: consolidar achados P0/P1 por severidade, validar que cada
rota sensível tem auth + ownership-scope, e re-auditar depois de
qualquer fix (nada de despachar cego).
7. VERIFICAR (ownership): para rotas com `:id`, conferir que a query usa o
ID autenticado — `grep -rn "user_id\|user.id\|req.user" src/ | wc -l`
>= número de rotas protegidas.
8. VERIFICAR (rate limit): `grep -rniE "ratelimit|rate_limit|limiter" src/`
— toda rota de escrita tem rate limit de referência; se ausente, anotar
como P2.
9. VERIFICAR (headers/CORS): conferir CSP/CORS configurados (CORS
allowlist explícita, não `*` com credenciais); `grep -rn "access-control\|csp\|content-security" src/`.
10. VERIFICAR (re-audit pós-fix): após corrigir P0/P1, re-rodar
`bola-detector` + `api-security-review` e confirmar que os achados
sumiram (não só mudaram de arquivo).
11. VERIFICAR (critério de aceite de segurança): para cada achado P0/P1,
reexecutar o teste que o reproduzia e confirmar que agora passa;
manter o PoC no repositório de testes.
12. VERIFICAR (comandos de confirmação): `grep -c "auth\|ownership" src/`
deve ser >= número de rotas que mexem em dado de usuário — cada rota
sensível tem o controle por objeto documentado no código.
**Checklist da fase 3 (segurança):**
- [ ] `bola-detector` limpo em rotas com `:id` (object-level authz).
- [ ] Auth/RBAC (`auth-rbac-scaffold`) cobrindo roles e sessions.
- [ ] `injection-checker` limpo (SQL/ORM/shell/templates).
- [ ] `api-security-review` sem P0/P1 (OWASP API Top 10).
- [ ] `dependency-cve-audit` sem CVEs críticas pendentes.
**Anti-padrões desta fase:**
- NUNCA definir query escopada por outro ID que não o autenticado.
- NUNCA aceitar finding P0/P1 sem evidência de correção.
- NÃO revisar segurança só nos endpoints novos — escopar também os existentes.
- NÃO tratar auditoria como checklist burocrático: achado não resolvido bloqueia.
## Fase 4 — TEST + BUG HUNT (provar antes de entregar)
1. `hermaguard` no diff do backend — dispachar os 3 agentes adversariais
(Edge Case Hunter, Adversarial Reviewer, Blast Radius). Esperar falhar:
NUNCA parar em "parece ok"; exigir cobertura de edge cases, races,
rollback safety e schema drift. Read-only (não corrige — acha).
2. `test-driven-development`: testar o que valida/auth/idempotência.
3. `security-test-generator`: testes de segurança (authz negativa,
payloads malformados, rate limit).
4. Rodar suíte + lint + typecheck; status real, não suposição.
5. Corrigir os findings P0/P1 do hermaguard como tarefas separadas; rodar
hermaguard de novo se o fix mudou >3 arquivos.
6. Relatório: contrato entregue, achados de segurança P0/P1/P2 resolvidos,
bugs caçados pelo hermaguard (por severidade), testes passando (contagem).
7. VERIFICAR (não-regressão QA): rodar `test_quality.py` (gate do workflow)
— score não pode cair em relação ao baseline.
8. VERIFICAR (cobertura de classes): para rolls em produção, conferir que
o hermaguard cobriu edge cases, races, rollback safety e schema drift —
não aceitar "sem achados" sem essa cobertura.
9. VERIFICAR (efeito colateral): se a mudança alterou contrato/DB, rodar
`rest-graphql-debug` para confirmar status codes e mensagens sem
regressão.
10. VERIFICAR (cobertura de testes real): `python3 -m pytest --cov=app -q`
(ou `npm test -- --coverage`) — anotar % de cobertura e garantir que
os módulos críticos (auth, validação, idempotência) têm pelo menos
smoke test.
11. VERIFICAR (migração reversível): se houve schema change, rodar
`alembic downgrade -1`/equivalente em dev para provar rollback; e
`git diff --stat` para conferir o escopo do que está indo pra frente.
12. VERIFICAR (config por ambiente): `grep -rn "getenv\|os.environ\|process.env" src/` — toda configuração via env, sem valores hardcoded que
vazam para prod.
13. VERIFICAR (comandos de entrega): `python3 -m pytest -q && npm run build` (ou stack equivalente) como smoke final; e `git status` para
confirmar que os artefatos de teste não vazaram pro repo.
14. VERIFICAR (critério de entrega): relatório final só fecha quando cada
item do checklist da Fase 4 está marcado — sem exceção de última hora
não auditada.
**Checklist da fase 4 (gate de entrega):**
- [ ] `hermaguard` rodado; findings CRITICAL/HIGH zero ou com plano de fix.
- [ ] TDD: testes de validação, auth e idempotência verdes.
- [ ] `security-test-generator`: authz negativa, payloads mal, rate limit.
- [ ] Suíte + lint + typecheck verdes (contagem real, não suposição).
- [ ] Findings P0/P1 corrigidos e re-verificados (hermaguard rodado de novo
se o fix alterou >3 arquivos).
**Anti-padrões desta fase:**
- NUNCA rodar hermaguard em código com testes quebrados (polui o review).
- NUNCA dar "suíte passando" sem ter executado a suíte.
- NÃO aceitar "hermaguard não achou nada" sem exigir a cobertura por classe
(edge cases, races, rollback, schema drift).
- NÃO reportar achado P0/P1 como resolvido sem a verificação de volta.
## Comandos de Verificação (executáveis)
```bash
# Gate de qualidade do próprio workflow (sem regressão)
python3 ~/.hermes/skills/software-development/wf-qa/test_quality.py
# Testes + meta-testes (prova que o harness detecta regressão)
python3 ~/.hermes/skills/software-development/wf-qa/test_tests.py
# Audit OWASP de um endpoint/controller
# (skill api-security-review) — veja a skill
# CVE nas deps do projeto
# (skill dependency-cve-audit) — veja a skill
# Bug hunt adversarial no diff (read-only)
# (skill hermaguard: "hermaguard this")
```
## Critérios de Aceite (checklist não-regressivo)
- [ ] Contrato aprovado (PLAN) antes de qualquer handler.
- [ ] BUILD com defaults seguros; `secure-coding` validado na stack.
- [ ] SECURITY: bola/auth/injection/api-review/CVE rodados; P0/P1 resolvidos.
- [ ] TEST: hermaguard + TDD + security-test-generator; suíte verde com
contagem real.
- [ ] Nenhuma skill do stack removida do arquivo.
- [ ] Rodar `python3 ~/.hermes/skills/software-development/wf-qa/test_quality.py`
→ exit 0 (sem regressão).
## Exemplos de execução por fase (comandos reais)
Fase 1 — validar contrato antes de codar:
```bash
# Lista de rotas planejadas (contrato em aberto)
cat > docs/contract.md <<'EOF'
POST /api/v1/users -> 201 | 400 | 401 | 409 | 429
GET /api/v1/users/:id -> 200 | 404 | 403
Erros: RFC 9457 (application/problem+json)
EOF
```
Fase 2 — build seguro (exemplo FastAPI + Pydantic):
```bash
# Rodar a stack e conferir a OpenAPI gerada
uvicorn app.main:app --reload # ou npm run dev
curl -s localhost:8000/openapi.json | python3 -m json.tool > /tmp/openapi.json
python3 -c "import sys,json; d=json.load(open('/tmp/openapi.json')); print('schemas:', len(d.get('components',{}).get('schemas',{})))"
# Validação de contrato contra a OpenAPI real
curl -s localhost:8000/health -i | head -5 # status codes do health
curl -s -X POST localhost:8000/api/v1/users -d '{}' -i | head -5 # 400 esperado
```
Fase 3 — auditoria de segurança:
```bash
# Rodar as skills de auditoria OWASP (veja cada skill p/ uso exato)
# bola-detector: "audite rotas com :id" / auth-rbac-scaffold: "valide o fluxo de login"
# injection-checker: "escaneie SQL/ORM" / api-security-review: "revisão OWASP do conjunto"
# dependency-cve-audit: "audite as dependências" (skill local)
```
Fase 4 — testes e bug hunt:
```bash
python3 -m pytest -v # ou npm test
python3 ~/.hermes/skills/software-development/wf-qa/test_quality.py # gate do workfl
# "hermaguard this" (bug hunt adversarial no diff)
```
Gates anti-regressão (rodar junto com o fluxo):
```bash
python3 ~/.hermes/skills/software-development/wf-qa/test_tests.py # teste dos testes
# verifica que o harness DETECTA regressão (mutações sempre derrubam o score)
python3 -m pytest tests/security/ -x # se existir suíte de segurança
```
## Regras duras
- NUNCA escrever handler antes do contrato aprovado.
- NUNCA entregar endpoint sem passar pelas 4 fases (security + testes +
hermaguard).
- Rota que mexe em dado do usuário → ownership-check obrigatório (query
escopada ao ID autenticado).
- Tests vermelhos = fixar primeiro; hermaguard não roda em código quebrado.
+309
View File
@@ -0,0 +1,309 @@
---
name: wf-frontend
description: "Use p/ frontend/UI. Fluxo DESIGN→BUILD→REVIEW."
version: 1.0.0
author: Hermes Agent
license: MIT
platforms: [linux, macos, windows]
metadata:
hermes:
tags: [frontend, ui, ux, design, react, tailwind, workflow]
---
# Workflow Frontend/Design
Orquestrador obrigatório para TODO trabalho de frontend, UI, UX ou design
(componentes, páginas, landing, apps, re-design, design system). Processo de
3 fases com skills fixas por fase.
## When to Use
Sempre que a tarefa envolver interface do usuário ou GERAÇÃO DE PDF:
- Frontend/UI: criar/editar componentes React/Vue/Svelte, páginas, layouts,
estilos, animações, acessibilidade, qualquer pedido de "design"
- **PDF/DOCUMENTOS VISUAIS: SEMPRE via este workflow** (regra do Evandro,
ago/2026) — NUNCA reportlab platypus raw (estoura bordas em tabelas
longas). Usar HTML+CSS → Playwright headless (`pdf-generator`,
`html-css-print-engineer`, `pdf-render-qa`). Design primeiro, depois
render, depois QA visual (vision_analyze) antes de entregar.
- Vale para apps novos e refactors.
## Skills do stack (carregar conforme a fase)
- Direção visual / anti-AI-slop: `frontend-design` (Anthropic), `web-design`,
e locais `frontend-award-tier`, `claude-design`, `popular-web-designs`,
`anti-ai-slop`
- React/Next performance + composição: `vercel-react-best-practices`,
`vercel-composition-patterns`
- Motion: `animate` (emilkowalski)
- Bug hunting: `hermaguard` (pre-scan + 3 agentes adversariais; read-only)
- Qualidade de texto/UI copy: `avoid-ai-writing` (remove AI-isms de microcopy,
textos de componente, a11y labels, README de frontend)
- Esboço rápido / docs visuais: `sketch`, `design-md` (locais)
- PDF de qualidade: `pdf-generator` (HTML+CSS LaTeX → Playwright),
`html-css-print-engineer`, `pdf-render-qa` (QA), `professional-pdf-director`,
`pdf-visual-designer` — todo PDF passa por aqui
## Fase 1 — DESIGN (decidir antes de codar)
1. Carregar `frontend-design` + `frontend-award-tier` + `anti-ai-slop`.
2. Definir direção visual explícita: paleta, tipografia, espaçamento,
densidade, dark/light — NUNCA gerar "default AI slop".
3. Se for re-design/variação: `claude-design`/`popular-web-designs` para
basear em design systems reais (Stripe/Linear/Vercel) e fugir do genérico.
4. Documentar decisões em `DESIGN.md` (padrão `design-md` se aplicável).
5. Parar e validar a direção com o usuário ANTES de implementar.
6. VERIFICAR: rodar `avoid-ai-writing` em detect no DESIGN.md (0 AI-isms) e
confirmar que a direção está registrada (paleta + tipografia + density)
antes de codar.
7. VERIFICAR (gate visual): se for PDF/artefato visual, renderizar um
rascunho e inspecionar com `vision_analyze` ANTES de avançar — validar
que a direção visual de fato foi aplicada e nada está fora de margem.
8. CHECKPOINT: gravar decisões (paleta final, fonte, density) num
`DESIGN.md` com versionamento, para as fases seguintes referenciarem.
9. VERIFICAR (comandos de direção): conferir que `DESIGN.md` existe e tem
conteúdo — `wc -l DESIGN.md` > 5; e que as cores/fontes estão anotadas
(`grep -c "paleta\|fonte\|spacing" DESIGN.md` >= 3).
10. VERIFICAR (anti-slop real): rodar o `anti-ai-slop` no direção proposta
antes de mostrar ao usuário — detectar gradiente/glassmorphism
prematuramente economiza retrabalho.
11. VERIFICAR (comandos de design): validar a direção também contra a
ferramenta de design usada — `npx`/CLI do design system (ex:
`pnpm tailwindcss` se Tailwind) confirmando tokens aplicáveis; e
checar com `grep -rn "palette\|tokens\|--color" DESIGN.md` que os
tokens ficaram declarados.
**Checklist da fase 1 (validar todos antes de seguir):**
- [ ] Direção visual definida e DOCUMENTADA (paleta, tipografia, spacing).
- [ ] Anti-slop: nenhum padrão "default IA" (gradiente, glassmorphism, ícones genéricos).
- [ ] `DESIGN.md` existe e está aprovado pelo usuário.
- [ ] `avoid-ai-writing` detect = 0 no DESIGN.md.
**Anti-padrões desta fase:**
- NUNCA pular a definição de direção visual "só para ver como fica".
- NUNCA aprovar design sem a confirmação explícita do usuário.
- NÃO misturar 2 design systems na mesma tela; se for variação, basear em um só.
## Fase 2 — BUILD (implementar com padrões de produção)
1. Carregar `vercel-react-best-practices` + `vercel-composition-patterns`
(React) — aplicar regras de performance (waterfalls, bundle, re-renders)
e composição (compound components, sem boolean-prop explosion).
2. Componentes acessíveis por padrão (WCAG): semântica HTML, foco,
contraste — sem depender de ARIA desnecessário.
3. Animações só quando agregam: `animate` — propósito, duração, easing,
reduzir motion para prefers-reduced-motion.
4. Responsivo mobile-first; estados vazios/loading/erro em todo fluxo.
5. VERIFICAR: rodar build + lint incrementalmente a cada componente
(npm/pnpm build) e `vercel-react-best-practices` como checklist de perf
durante o build — não deixar para o fim.
6. VERIFICAR (a11y atômica): para cada componente novo, conferir semântica
HTML, gerenciamento de foco e contraste ANTES de considerar pronto —
acessibilidade é parte do build, não polimento final.
7. VERIFICAR (perf real): medir com DevTools/Lighthouse por tela-chave
(LCP, INP, CLS) e registrar os números no relatório de perf.
8. VERIFICAR (composição limpa): `grep -rn "is[A-Z]\|show[A-Z]" src/components`
para caçar boolean-prop explosion (deve ser 0 ou poucos intencionais);
se houver, refatorar para compound components.
9. VERIFICAR (animações justificadas): para cada `animate`/motion adicionada,
conferir com `grep -rn "animate\|transition\|motion" src/` que há propósito
(hover/estado/entrada) — animação decorativa sem função = cortar.
10. VERIFICAR (limpeza): `git status` e `git diff --stat` antes de fechar —
nada de arquivo órfão/debug commitado.
11. VERIFICAR (critério de aceite do componente): cada componente novo
confirma o critério definido na Fase 1 (estado correto, a11y ok, perf
ok) antes de passar para o próximo — validar item a item do checklist.
12. VERIFICAR (comandos de estado): conferir que loading/erro/vazio são
tratados em cada fluxo — `grep -rn "loading\|isLoading\|error\|empty" src/`
para provar a presença nos componentes que interagem com dados.
13. VERIFICAR (anti-padrão visual final): percorrer os componentes com
`anti-ai-slop` de novo ao fechar a fase — sombra/glassmorphism que
"escapou" no scroll é regressão de qualidade.
14. VERIFICAR (critério de aceite): validar que cada item do checklist da
fase está marcado (sem checkbox em branco) antes de declarar BUILD
concluído.
**Checklist da fase 2 (validar antes da REVIEW):**
- [ ] Build e lint verdes (`npm run build` / `npx tsc --noEmit`).
- [ ] Componentes acessíveis (semântica HTML, foco, contraste) — auditar com
`frontend-design`/a11y antes de considerar pronto.
- [ ] Estados vazios/loading/erro presentes em todo fluxo.
- [ ] Animações com propósito + `prefers-reduced-motion` respeitado.
**Anti-padrões desta fase:**
- NUNCA usar `any`/forçar cast em TS para "fazer passar".
- NUNCA animar sem propósito — animação decorativa gratuita é anti-padrão.
- NÃO implementar responsivo só no final; mobile-first desde o início.
- NÃO duplicar lógica de estado em vários componentes (compor, não copiar).
## Fase 3 — REVIEW (verificar antes de entregar)
1. `anti-ai-slop` sobre o resultado (gradientes-texto, glassmorphism,
sombras genéricas, layout previsível).
2. `avoid-ai-writing` sobre textos entregues ao usuário: microcopy, labels,
empty states, mensagens de erro, README/descrições — remover AI-isms
(em-dash em excesso, "robust", "seamless", "let's dive in", etc).
3. `hermaguard` no diff de frontend (JS/TS/TSX/CSS): caça bugs adiversariais
no código produzido (lógica de estado, efeitos, a11y que quebra).
4. `vercel-react-best-practices` como checklist de perf (LCP/INP/CLS,
bundle, imagem, Suspense).
5. Rodar build + lint + testes do projeto; corrigir o que quebrar.
6. Relatório curto: o que foi decidido na Fase 1, entregue na 2, verificado
na 3.
7. VERIFICAR (regressão visual): se houver, comparar screenshots do antes
vs depois (ou `vision_analyze` no render) para garantir que nada quebrou
de layout.
8. VERIFICAR (não-regressão QA): rodar `test_quality.py` (gate do workflow)
e conferir que o score do stack não caiu.
9. VERIFICAR (hermaguard re-audit): se o REVIEW mudou >3 arquivos, rodar
`hermaguard` no novo diff antes de fechar.
10. VERIFICAR (bundle/perf real): rodar `npm run build` e conferir tamanho
dos chunks (`ls -lh dist/static/*.js`), anotar LCP/INP/CLS se houver
Lighthouse.
11. VERIFICAR (html válido): para PDF/páginas, validar o HTML antes do
render — `python3 -c "from html.parser import HTMLParser; ...
"` (ou parser disponível) e `grep -c "</t" arquivo.html` = 0 (sem tag
truncada).
12. VERIFICAR (comandos de acessibilidade): rodar auditoria de a11y no
render final — `npx @axe-core/cli http://localhost:PORT` (se houver
dev server) ou `pa11y`/equivalente; anotar violações sérias.
13. VERIFICAR (contraste verificado): para paleta dark/light, conferir
contraste com ferramenta (ex: `npx contrast-checker` ou manual) —
textos principais >= 4.5:1.
**Checklist da fase 3 (gate de entrega):**
- [ ] `anti-ai-slop` aplicado e sem ressalvas no resultado final.
- [ ] `avoid-ai-writing` detect = 0 em microcopy/labels/errors/README.
- [ ] `hermaguard` rodado no diff (0 findings CRITICAL/HIGH pendentes).
- [ ] `vercel-react-best-practices` auditado (LCP/INP/CLS, bundle, imagem).
- [ ] Build + lint + testes verdes com contagem real.
- [ ] Para PDF: renderização via Playwright + `vision_analyze` sem corte.
**Anti-padrões desta fase:**
- NUNCA dar como entregue com build vermelho.
- NUNCA ignorar finding CRITICAL/HIGH do hermaguard "para depois".
- NÃO pular o QA visual de PDF (conteúdo cortado nas bordas = entrega quebrada).
- NÃO entregar relatório sem os itens do checklist marcados.
## Comandos de Verificação (executáveis)
Gate de qualidade do stack (rodar SEMPRE antes de entregar):
```bash
# 1) Não-regressão: valida que os workflows continuam íntegros
python3 ~/.hermes/skills/software-development/wf-qa/test_quality.py
# 2) Testes-dos-testes: prova que o harness detecta regressão
python3 ~/.hermes/skills/software-development/wf-qa/test_tests.py
```
QA visual de PDF — renderizar páginas e inspecionar bordas (nada cortado):
```bash
cd ~/.hermes/skills/productivity/pdf/scripts
python pdf_page_image.py /caminho/do.pdf --pages 1-3 --dpi 150 --out-dir /tmp/qa
# depoiss: vision_analyze em cada PNG — margens ok, sem truncamento
```
Qualidade de texto (microcopy, labels, README) — auditoria de AI-isms:
```bash
# detect (só lista) — passa 2 arquivos para comparar original vs limpo
node ~/.hermes/skills/avoid-ai-writing/detector/validate.js ui-copy.md ui-copy-limp.md
# ou debaixo do wf: pedir "roda o avoid-ai no README" (modo detect/rewrite)
```
Bug hunt adversarial no diff (comandos da skill hermaguard):
```bash
# gatilho: "hermaguard this" / "adversarial review" / "bug hunt this"
# gera relatório em /tmp/hermaguard/hermaguard-<ts>.md + .json
```
Performance React/Next — checklist durante o build:
```bash
npm run build # ou pnpm build — verificar warnings de bundle chunk
npx tsc --noEmit # typecheck limpo
npm run lint # sem erros
```
Resumo do fluxo (mapa de navegação do workflow):
```text
[Fase 1 DESIGN] -> frontend-design + anti-ai-slop -> DESIGN.md aprovado
[Fase 2 BUILD] -> vercel patterns + animate -> build/lint verdes
[Fase 3 REVIEW] -> avoid-ai + hermaguard + perf -> QA visual (PDF)
[Gate final] -> test_quality.py exit 0
```
## Critérios de Aceite (checklist não-regressivo)
- [ ] DESIGN.md com direção visual aprovada (Fase 1 validada pelo usuário).
- [ ] BUILD com perf/a11y; build e lint verdes a cada componente.
- [ ] REVIEW: anti-ai-slop + avoid-ai-writing + hermaguard + perf checklist.
- [ ] Para PDF: renderização via Playwright e QA visual (vision_analyze)
sem conteúdo cortado nas bordas.
- [ ] Nenhuma skill do stack removida do arquivo.
- [ ] Rodar `python3 ~/.hermes/skills/software-development/wf-qa/test_quality.py`
→ exit 0 (sem regressão).
## Exemplos de execução por fase (comandos reais)
Fase 1 — direção visual documentada:
```bash
cat > DESIGN.md <<'EOF'
# Direção visual
Paleta: fundo #ffffff, acento #1e40af, texto #1a1a1a
Tipografia: serif corpo (Noto Serif/Georgia), mono p/ código
Density: padrão; dark/light: light first
EOF
```
Fase 2 — build e perf:
```bash
npm run build # ou pnpm build
npx tsc --noEmit # typecheck
npm run lint # sem erros
# "audite a perf" (vercel-react-best-practices)
```
Fase 3 — review/QA:
```bash
# "rode o anti-ai-slop" / "rode o avoid-ai nos textos"
# "hermaguard this" (bug hunt no diff de frontend)
```
Para PDF (regra do Evandro — SEMPRE este caminho):
```bash
# HTML+CSS -> Playwright headless
~/.hermes/venvs/latebra/bin/python /tmp/gen-pdf.py # ver pdf-generator
cd ~/.hermes/skills/productivity/pdf/scripts
python pdf_page_image.py saida.pdf --pages 1-N --dpi 150 --out-dir /tmp/qa
# depois vision_analyze em cada PNG: NENHUM conteúdo cortado nas bordas
# QA de perfil visual (se tiver origem de design)
node ~/.hermes/skills/avoid-ai-writing/detector/validate.js ui-copy.md ui-limp.md
```
Verificação de integridade do workflow (gate anti-regressão):
```bash
python3 ~/.hermes/skills/software-development/wf-qa/test_quality.py # não-regressão
python3 ~/.hermes/skills/software-development/wf-qa/test_tests.py # teste dos testes
# "hermaguard this" -> bug hunt adversarial se o diff >3 arquivos
# "rode o anti-ai-slop" -> antes de entregar
```
## Regras duras
- NUNCA pular a Fase 1 (consulta de design) direto para código.
- NUNCA entregar UI sem passar pelo `anti-ai-slop` + `avoid-ai-writing` +
`hermaguard` + build verde.
- Dúvida de stack (Vite vs Next, Tailwind vs CSS) → decidir na Fase 1 com
aprovação do usuário, não no meio do build.
+209
View File
@@ -0,0 +1,209 @@
---
name: wf-security-review
description: "Code review de segurança (front+back). OSV/NVD + OWASP."
version: 1.0.0
author: Hermes Agent
license: MIT
platforms: [linux, macos, windows]
metadata:
hermes:
tags: [security, code-review, cve, owasp, sast, sca, workflow, devsecops]
---
# Workflow Security Code Review (front + backend)
Orquestrador obrigatório para todo code review de segurança — frontend E
backend. Cobre: revisão de código (OWASP), vulnerabilidades conhecidas em
dependências, E consulta de NOVAS vulnerabilidades nos lugares certos
(OSV.dev, NVD, GitHub Advisory) para que o review esteja sempre atualizado,
não preso ao cutoff de treino do modelo.
## When to Use
- "revisa a segurança desse código/PR/diff" (front ou back)
- "escaneia dependências por CVEs" / "alguma lib vulnerável?"
- "tem vulnerabilidade nova conhecida pra X?" (consulta de atualização)
- "audita auth/API/injeção" / "procura segredos commitados"
- QUALQUER review de merge que mexa em dado sensível ou rota nova
- Pré-commit ou pré-deploy como etapa de segurança
## Skills do stack (3 principais + auxiliares)
**As 3 skills de segurança atuais (instaladas de fontes primárias):**
1. `safedeps` (Jeneidi) — grounding em OSV.dev em tempo real: consulta
`package@version` e traz CVE com severidade e fix. Cobre o gap de o
modelo só conhecer vulns até o cutoff. CLI: `check_deps.py`.
2. `sca-audit` (OWASP secure-agent-playbook) — SCA (Supply Chain Analysis)
de dependências com análise de alcance (reachability), CWE mapping.
3. `code-review-security` (OWASP secure-agent-playbook) — code review de
segurança sistemático mapeado a OWASP Top 10 + ASVS.
**Auxiliares (carregar por contexto):**
- `secrets-scan` (OWASP) — busca credenciais/API keys no código e git history
- `api-security-review` + `bola-detector` + `auth-rbac-scaffold` +
`injection-checker` (OWASP/API) — revisão de API
- `web-security-review` (OWASP) — web app OWASP Top 10
- `cve-triage` + `patch-prioritization` (UnitOne/SecuritySkills) — priorizar
CVE por CVSS 4.0 / EPSS / CISA KEV
- Locais: `dependency-cve-audit`, `hermaguard` (caça bugs adversariais),
`security-threat-model`
## Fase 1 — SCOPE (definir alvo antes de auditar)
1. Identificar o que está no escopo: diff/PR, arquivos, front, back, ambos.
2. Registrar stack do projeto (linguagens, frameworks, package managers,
se há lockfile: package-lock.json / requirements.txt / go.mod / etc).
3. Rodar o código? Identificar se há ambiente local testável.
4. VERIFICAR: `git status` + `git diff --stat` para delimitar o alvo real.
5. Checkpoint: confirmar escopo com o usuário antes de gastar auditoria.
**Checklist da fase 1:**
- [ ] Escopo delimitado (arquivos/diff/PR)
- [ ] Stack e lockfiles identificados
- [ ] Alvo confirmado
## Fase 2 — HUNT (vulnerabilidades conhecidas — dimensão de dependências)
1. `sca-audit` — scan de dependências com análise de alcance; mapear CVEs
por severidade e reachable/unreachable.
2. `safedeps` — para cada dependência-chave do manifest, consultar OSV.dev:
`python3 ~/.hermes/skills/safedeps/check_deps.py "pkg@version"` (ou via
manifest completo) — traz CVE reais com fix (o modelo NÃO sabe CVE nova
do cutoff pra frente; o OSV.dev sim).
3. `cve-triage` / `patch-prioritization` — priorizar achados por
CVSS 4.0 / EPSS / CISA KEV quando disponível.
4. `dependency-cve-audit` (local) — varredura das deps do projeto atual.
5. VERIFICAR: consolidar lista de CVE com severidade + versão afetada +
versão fixa; separar reachable (devem ser bloqueantes) de non-reachable
(registrar como risco residual).
6. CHECKPOINT: apresentar sumário de CVE antes de partir para o code review.
**Comandos úteis:**
```bash
python3 ~/.hermes/skills/safedeps/check_deps.py "[email protected]" # 1 pkg
python3 ~/.hermes/skills/safedeps/check_deps.py -f package-lock.json # manifest
# veja a skill sca-audit p/ reachability; cve-triage p/ priorização
```
**Anti-padrões desta fase:**
- NUNCA afirmar "sem CVE" sem ter CONSULTADO OSV.dev (memória do modelo é
congelada no cutoff).
- NÃO tratar CVE de dependência transitiva não-reachable como crítica igual
a reachable — reportar com nuance.
- NUNCA rodar scan em lockfile sem conferir o package manager certo.
**Comandos reais (Fase 2):**
```bash
python3 ~/.hermes/skills/safedeps/check_deps.py "[email protected]"
python3 ~/.hermes/skills/safedeps/check_deps.py -f package-lock.json
# alternatives: npm audit --json / pip-audit -r requirements.txt / trivy fs .
```
## Fase 3 — CONSULT (novas vulnerabilidades — atualização contínua)
O objetivo é responder "há vulnerabilidade NOVA que eu não conheço?" — o
modelo só sabe até o cutoff; consultar fontes vivas:
1. OSV.dev (API aberta, sem key) — já coberto na Fase 2 via safedeps.
2. GitHub Advisory Database — via `gh api`:
`gh api graphql -f query='{securityAdvisories(first:10, orderBy:{field:PUBLISHED_AT,direction:DESC}){nodes{ghsaId,summary,severity,publishedAt}}}'
3. NVD — via API (key opcional): consultar CPE do stack ou CVEs recentes do
framework em uso (`curl -s "https://services.nvd.nist.gov/rest/json/cves/2.0?keywordSearch=..."`).
4. Registros de framework (ex: changelog/security de Next.js, Express,
NestJS, FastAPI) — advisories recentes do framework do projeto.
5. VERIFICAR: para LIB versão X e FRAMEWORK Y, registrar qual fonte foi
consultada e a data — sem "não tem" sem fonte.
6. CHECKPOINT: se alguma vuln nova afeta o stack do projeto, tratar como
finding HIGH e sugerir upgrade.
**Comandos úteis:**
```bash
gh api graphql -f query='{securityAdvisories(first:10, orderBy:{field:PUBLISHED_AT,direction:DESC}){nodes{ghsaId,summary,severity,publishedAt}}}'
curl -s "https://services.nvd.nist.gov/rest/json/cves/2.0?keywordSearch=nextjs&resultsPerPage=10"
# OSV batch: curl -s -X POST https://api.osv.dev/v1/querybatch -d '@manifests.json'
```
**Anti-padrões desta fase:**
- NUNCA responder "não tem vulnerabilidade nova" sem citar fonte viva + data.
- NÃO confiar no cutoff do modelo para saber CVE recente — sempre consultar.
- NÃO esquecer de incluir data da consulta (revisão vence se ficar velho).
## Fase 4 — CODE REVIEW (front + backend, OWASP)
Frontend (`web-security-review` + `code-review-security`):
1. XSS/injeção em renderização (dangerouslySetInnerHTML, v-html, innerHTML).
2. Exposição de segredos no client (API keys, tokens em bundle).
3. Containers: loads, links com user input, cookies httpOnly/secure.
4. `secrets-scan` — credenciais no código e git history.
5. Auth de frontend: fluxo de tokens, storage inseguro (localStorage p/ JWT).
Backend (`code-review-security` + `api-security-review` + `bola-detector` +
`auth-rbac-scaffold` + `injection-checker`):
1. AuthN/AuthZ: rotas sem auth, IDOR/BOLA (`bola-detector`), RBAC.
2. Input validation: SQLi, XSS, command injection, SSRF, path traversal
(`injection-checker`).
3. Segredos: env vars, nunca logar senha/token.
4. Rate limit, erros sem vazar stack trace, CORS correto.
5. `hermaguard` (opcional) p/ caça adversarial de bugs no mesmo diff.
6. VERIFICAR: para cada rota com `:id`, rodar `bola-detector` de novo (IDOR
é o achado nº1 em API) e para cada query, `injection-checker`.
7. VERIFICAR: rodar `secrets-scan` no diff E git history antes de fechar —
credencial commitada em algum commit antigo ainda vaza.
8. VERIFICAR: conferir erros sem stack trace (grep por exceptions/console no
cliente) e CORS/headers (`grep -rn "access-control\|csp"`).
9. VERIFICAR: `grep -rn "localStorage\|sessionStorage" src/` — nenhum JWT
sensível em storage de frontend (usar httpOnly cookie).
10. VERIFICAR: confirmar rate limit em rotas de escrita (`grep -rniE "limiter|rate"`) e que respostas não vazam caminho interno.
**Output por finding:** Severidade (Critical/High/Med/Low) + CWE + OWASP ref +
Arquivo:linha + Evidência + Remediação.
**Anti-padrões desta fase (front + back):**
- NUNCA approve sem reportar achado de AuthN/AuthZ ou injection como mínimo.
- Padrão de coerência — NÃO misturar "parece ok" com achado sem evidência.
- NÃO confundir "não achei com grep" com "não existe" — checar fluxo inteiro.
- NÃO focar só no front quando o fix toca o back (IDOR/BOLA vive no back).
**Comandos de auditoria (Fase 4):**
```bash
# segredos: busca em código e git history
grep -rniE "(api[_-]?key|secret|password|token|bearer)" src/ | grep -v node_modules
git log -p --all -S "sk-" --oneline | head # chave vazada em commit antigo
# headers/CORS/rate limit
grep -rniE "access-control|content-security-policy" src/
grep -rniE "ratelimit|rate_limit|limiter|express-rate" src/
python3 ~/.hermes/skills/software-development/wf-qa/test_quality.py # gate
```
## Fase 5 — REPORT + GATE (entregar e decidir)
1. Consolidar tudo: sumário (nº por severidade), findings detalhados,
tabela de CVE com fonte/estado/reachable/fix, e status "consulta de
atualização feita em <data> via <fontes>".
2. GATE: Critical/High reachable → BLOQUEAR merge até corrigir. Medium →
tratar no próximo ciclo. Low/residual → registrar risco aceito.
3. Re-auditar após fixes: re-rodar as checagens que acusaram P0/P1.
4. VERIFICAR: `python3 ~/.hermes/skills/software-development/wf-qa/test_quality.py`
(gate não-regressivo do stack de workflows).
5. Relatório final em markdown (report.md) + resumo em chat.
6. VERIFICAR (comandos de report): gerar `security-report.md` com
`find . -maxdepth 2 -name "*.md" | sort` conferindo artefatos, e
`grep -c "CVE-" security-report.md` para ter contagem explícita no doc.
7. VERIFICAR (data da consulta): `grep -i "data da consulta\|20[2-9][0-9]-" security-report.md` — sem revisão sem carimbo de data (ela vence).
**Checklist de entrega:**
- [ ] Os 3 pilares rodados: safedeps (OSV), sca-audit, code-review-security.
- [ ] Consulta de novas vulns feita em fonte viva (OSV/GH Advisory/NVD) com data.
- [ ] Findings com CWE + OWASP + evidência + remediação.
- [ ] GATE aplicado (block/allow) por severidade/reachability.
- [ ] Nenhuma skill do stack removida; test_quality.py passando.
## Regras duras
- NUNCA afirmar "sem vulnerabilidades" sem consultar OSV.dev/GH Advisory
(modelo tem cutoff; fonte viva não).
- NUNCA reportar CVE sem incluir versão afetada + versão fixa.
- NUNCA blocker Critical/High reachable "para depois" — bloquear merge.
- NUNCA logar/expor segredo durante o review (nem no relatório).
- Re-auditar sempre que o fix tocar >3 arquivos ou mudar dependência.
- SQL/queries: sempre parâmetros posicionais, nunca concatenação de input.