@innleaders/review
v0.4.1
Published
Gate de conformidade InnLeaders — lib + CLI que analisa um projeto consumidor e reprova violações objetivas das políticas (fail) e sinaliza as heurísticas (warn)
Readme
@innleaders/review
Gate de conformidade verificável da governança InnLeaders. Analisa um diretório de projeto consumidor e emite o scorecard canônico da casa — o mesmo contrato de saída dos juízes dos squads (A7-guardian, D3, E4, S3), especificado em
docs/ai-automation/blueprint-esteira-criativa.md§6. "Pronto" passa a ser "veredito APROVADO".
Este pacote executa todo o [MECÂNICO] — os critérios de aderência que um script determinístico consegue provar. O juiz do squad recebe este scorecard e só acrescenta os itens de [JULGAMENTO] (os que exigem visão/semântica) na mesma lista, com o mesmo vocabulário. Um único vocabulário de conformidade no ecossistema inteiro.
A mesma lib serve três superfícies: o CLI local (este pacote), a futura tool review do MCP e o check de CI no repo consumidor.
O que checa (v1)
| Regra | Tipo | Severidade | Responsável | O que pega |
|---|---|---|---|---|
| AGENTS.md §Cores — regras rígidas | MECANICO | ALTA | A6-builder | Cor hex em .ts/.tsx/.js/.jsx/.css fora dos tokens. Escape documentado: hex-ok na linha. |
| motion.md R1 | MECANICO | ALTA · BAIXA | A6-builder | Duração/easing crus inequívocos = ALTA: duration-[…] (Tailwind), cubic-bezier(, transition: all 300ms, duration: 0.3 em prop de animação. Casos ambíguos (duration: 300 inteiro, tempo literal em CSS) = BAIXA (heurística de baixa confiança, pede conferência). Escape: motion-ok na linha. |
| orchestration.md §As regras — contrato de saída do A5 | MECANICO | ALTA | A5-motion | motion-spec.md ausente na raiz e em docs/ (só landing-page). |
| conversion.md N3 | MECANICO | ALTA | A6-builder | <TrustBand sem prop clients — cairia na lista default: prova alheia apresentada como real. |
| AGENTS.md §Regra nº 1 — não reinvente | MECANICO | ALTA · BAIXA | A6-builder | Reveal cru de @innleaders/motion no mesmo arquivo que blocos de @innleaders/marketing = ALTA (dois ritmos na página); sem a mistura = BAIXA (preferência de composição). Só landing-page. |
| motion.md R6 | MECANICO | MEDIA | A6-builder | @keyframes/animation: custom em CSS sem prefers-reduced-motion no mesmo arquivo (a11y — não é cosmético). |
| orchestration.md §As regras — contratos tipados (A1–A3) | MECANICO | MEDIA | A1 · A2 · A3 | Ausência de estrategia.md, copy.md, direcao-arte.md (1 item cada, com o autor do artefato como responsável). Sem eles o juiz não audita o [JULGAMENTO]. Só landing-page. |
| conversion.md R7 | MECANICO | MEDIA | A6-builder | <Button/<a com texto de CTA aparente sem data-cta (N6 bloqueia o publish; a detecção é heurística, por isso MEDIA). |
Em esteira de software (kind
ui), o papel equivalente aoA6-builderé oE2-dev— mesma regra, mesmo retrabalho, outro roster.
Diretórios ignorados: node_modules, dist, build, .next (e .git, .turbo, coverage).
Veredito
| Situação | Veredito | Exit code |
|---|---|---|
| Qualquer violação ALTA | REPROVADO | 1 |
| Violações só MEDIA/BAIXA | APROVADO_COM_RESSALVAS | 0 |
| Nenhuma violação | APROVADO | 0 |
Ressalva é decisão humana, não bloqueio de CI — por isso só REPROVADO derruba o pipeline. Erro de uso sai 2.
CLI
innleaders-review <kind> [dir] [--entrega <nome>] [--json]
# kind: landing-page | ui · dir default: . · entrega default: nome da pasta
innleaders-review landing-page ./apps/lp-tallky --entrega lp-tallky
innleaders-review ui . --jsonO relatório legível traz o veredito no topo, as violações como regra · severidade · responsável + evidência, o retrabalho agrupado por agente e o resumo conforme / violações / n/a. --json emite o scorecard cru (para pipelines, para o MCP e para o juiz continuar preenchendo).
API programática
import { runReview } from '@innleaders/review';
const scorecard = await runReview('landing-page', {
dir: './apps/lp-tallky',
entrega: 'lp-tallky', // opcional — default: nome da pasta
});{
"entrega": "lp-tallky",
"data": "2026-08-13T18:51:34.506Z", // ISO, gerado no ponto de entrada
"politicas_versao": { "motion": "1.0", "conversion": "1.0" },
"itens": [
{ "regra": "motion.md R1", "tipo": "MECANICO", "status": "CONFORME", "id": "motion-tokens-only" },
{ "regra": "conversion.md N3", "tipo": "MECANICO", "status": "VIOLACAO",
"evidencia": "src/page.tsx:7 — <TrustBand> sem prop clients …",
"responsavel": "A6-builder", "severidade": "ALTA",
"id": "trustband-no-default-clients", "arquivo": "src/page.tsx", "linha": 7 }
],
"resumo": { "conforme": 6, "violacoes": 1, "na": 1 },
"veredito": "REPROVADO",
"retrabalho": [{ "agente": "A6", "instrucao": "corrigir 1 violação(ões) mecânica(s) …" }]
}Detalhes do contrato:
- Regra sem violação vira item
CONFORME— o scorecard mostra o que foi provado, não só o que falhou. - Regra que não se aplica ao
kindnão vira item: entra na contagemnado resumo. id,arquivo,linhasão extensões aditivas para tooling (CI, MCP, anotação em editor). O contrato canônico exige sóevidencia, que por isso é autocontida (trazarquivo:linhano texto) — a duplicação é deliberada: o juiz cita o item inteiro como lastro, a máquina lê o campo estruturado.politicas_versaotraz só as políticas cuja versão é determinável no repo:motion.mdeconversion.mddeclaramv1.0no cabeçalho.AGENTS.mdainda não é versionado — fica de fora em vez de receber um número inventado. A política de orquestração ganhou versão (v1.0, 20/08/2026); preencherpolitica.versaonas regras que a citam é follow-up registrado. Quando um arquivo ganhar cabeçalho de versão, basta preencherpolitica.versaona regra.
Em CI (repo consumidor)
# .github/workflows/review.yml
name: innleaders-review
on: [pull_request]
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with: { node-version: 22, registry-url: 'https://registry.npmjs.org' }
- run: pnpm install
- run: pnpm exec innleaders-review landing-page .
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} # npm privado @innleadersO step falha (exit 1) em REPROVADO — o PR não merga com violação ALTA aberta.
Estendendo
Cada regra é um módulo em src/rules/*.ts implementando o contrato Rule e registrado em src/rules/index.ts:
export const minhaRegra: Rule = {
id: 'minha-regra',
regra: 'conversion.md R4', // a citação que o juiz mostra como lastro
tipo: 'MECANICO',
severidade: 'MEDIA', // padrão; cada achado pode sobrepor
responsavel: 'A6-builder', // padrão; cada achado pode sobrepor
politica: { id: 'conversion', versao: '1.0' },
kinds: ['landing-page'], // ausente = todos os kinds
check(ctx) { return [{ file, line, evidencia: '…' }]; },
};As regras são puras: recebem os arquivos já carregados e devolvem achados. Data, veredito, resumo e retrabalho são montados no ponto de entrada (runReview) — o que as mantém determinísticas e testáveis. Regras semânticas por LLM ficam fora deste pacote: aqui só entra o objetivamente checável por máquina ([MECÂNICO]).
