drift-check — CI gate¶
CLI standalone pra falhar o build de CI quando specs estão fora de sincronia com o código.
Exit codes:
| Code | Significado |
|---|---|
| 0 | Limpo — sem drift no severity escolhido |
| 1 | Drift detectado — bloqueia o build |
| 2 | aegis/reports/drift.md ausente — projeto não inicializado |
Opções¶
--severity¶
| Nível | O que bloqueia |
|---|---|
| high (padrão) | Apenas specs 🔴 pending |
| medium | 🔴 pending + 🟡 stale |
| low | Nada — sempre exit 0, só reporta contagens |
--format¶
| Formato | Saída |
|---|---|
| text (padrão) | Resumo legível + lista + dica de fix |
| json | Payload estruturado pra ferramentas de CI |
--folder¶
Override do output folder. Por padrão lê output_folder de aegis/config/state.json com fallback aegis.
Por que importa¶
Sem este gate, o drift loop é puramente disciplina humana. Hooks enfileiram eventos, Keeper atualiza specs — mas nada impede um PR de mergear com specs ainda em pending.
drift-check fecha o ciclo: build que tenta enviar drift não-resolvido falha. Desenvolvedores ou rodam /aegis-keeper after pra resolver, ou explicitamente baixam a severidade (com justificativa) pra aquele PR.
Exemplos de CI¶
GitHub Actions¶
# .github/workflows/ci.yml
jobs:
drift-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npx aegis-spec drift-check --severity high --format json
GitLab CI¶
pre-push hook genérico¶
#!/bin/sh
# .git/hooks/pre-push
if ! npx aegis-spec drift-check --severity high; then
echo "Push bloqueado. Rode /aegis-keeper after pra resolver."
exit 1
fi
Engine-agnostic¶
Esse comando NÃO carrega código de agente, chalk, inquirer ou geradores de hook. Só:
- Lê
aegis/config/state.jsonpra achar output folder (best-effort) - Parseia a tabela markdown em
aegis/reports/drift.md - Conta status
- Sai
Cold start rápido (sem imports pesados), serve em qualquer CI runner.
Schema JSON¶
{
"severity": "high",
"source": "/abs/path/to/aegis/reports/drift.md",
"counts": { "pending": 1, "stale": 2, "resolved": 12 },
"blocking": [
{ "spec": "sdd/notifications.md", "status": "pending", "action": "Rodar /aegis-keeper after" }
],
"clean": false
}
Quando aegis/reports/drift.md está ausente, saída JSON:
{
"error": "drift.md not found",
"path": "/abs/path/to/aegis/reports/drift.md",
"hint": "Rode /aegis pra inicializar, depois /aegis-keeper after pra popular drift.md"
}
Veja também¶
- Agente Keeper — quem popula o
drift.md - Hooks — auto-trigger do Keeper por edição de arquivo