Audit Frontmatter
audit specs/audit/frontmatter.kmd
Convenção do bloco `audit:` em frontmatter YAML de specs e policies. Permite que a engine `koder-spec-audit` descubra dinamicamente quais módulos auditar contra cada spec/policy, sem hardcoding em comando. Toda spec/policy auditável segue este schema.
Quando esta spec se aplica
Todos os triggers
- Criar spec ou policy nova
- Adicionar enforcement automático a spec/policy existente
- Implementar engine koder-spec-audit (ETAPA 1.5 do KSTACK-101)
Corpo da especificação
Spec — Audit Frontmatter
Toda spec ou policy que pode ser auditada automaticamente declara um bloco
audit: no frontmatter YAML. A engine koder-spec-audit percorre todos os
arquivos .kmd em meta/docs/stack/{specs,policies}/, lê este bloco, e
executa o audit script contra os módulos que casam com applicable_to.
Schema
audit:
applicable_to: # required: lista de seletores
- "<glob de paths>" # ex: "products/**/app/{mobile,desktop,web,tv}"
- "component_type in [<types>]" # alternativa: tipo da coverage-matrix
- "always" # caso especial: aplica a tudo
script: ./<filename>.sh # required: sibling do .kmd
severity: hard | advisory # required: hard bloqueia commit; advisory reporta
exit_codes: # optional: customizar exit codes
pass: 0
drift: 1
error: 2
output_format: json # optional: default json (RFC-001 §4)
Campos
applicable_to (required)
Lista de seletores que define quais módulos do monorepo são auditados contra esta spec/policy.
Forms aceitas:
| Form | Exemplo | Semântica |
|---|---|---|
| Glob de path | "products/**/app/{mobile,desktop,web,tv}" |
shell glob; expande pra lista de paths |
component_type in [...] |
"component_type in [app/desktop, app/web]" |
tipos canônicos da coverage-matrix meta/docs/stack/specs/testing/coverage-matrix.md |
always |
"always" |
aplica a Stack toda (ex.: policies/stack-principles.kmd) |
never |
"never" |
spec não-auditável programaticamente (raríssimo) |
Combinação: múltiplas linhas em applicable_to são tratadas como
união (OR). Pra interseção, expressar no script.
script (required)
Path relativo do audit script, sibling do arquivo .kmd. Convenção:
mesmo basename do .kmd + -audit.sh.
Ex.: policies/code-first.kmd → policies/code-first-audit.sh.
Tipo do arquivo: shell script (preferred), Python script, ou binário. Tem que ser executável.
Contrato:
#!/usr/bin/env bash
# Recebe: $1 = path absoluto do módulo a auditar
# Stdout: JSON com formato RFC-001 §4 (applied / deferred / errors)
# Stderr: warnings/info pra debug humano
# Exit:
# 0 = pass (sem drift)
# 1 = drift detectado (severity:hard bloqueia; severity:advisory reporta)
# 2 = erro interno do script (sempre abortar com mensagem)
severity (required)
| Valor | Quando | Audit failure |
|---|---|---|
hard |
spec normativa, conformidade testável | aborta pre-commit; bloqueia release |
advisory |
policy comportamental, princípio | só reporta no /k-housekeep Fase 0.5; não bloqueia |
Ver policies/stack-principles.kmd pra distinção spec vs policy.
exit_codes (optional)
Override padrão se o script tem semântica diferente. Default:
exit_codes:
pass: 0
drift: 1
error: 2
output_format (optional)
Default json per RFC-001 §4 do dev/koder-tools. Outras opções
(text, tap) podem ser adicionadas no futuro.
Exemplo completo
meta/docs/stack/specs/themes/ui-style.kmd (a criar em ETAPA 2.2):
---
name: UI Style
type: spec
mandatory: true
audit:
applicable_to:
- "products/**/app/{desktop,web}"
- "services/**/app/{desktop,web}"
script: ./ui-style-audit.sh
severity: hard
summary: |
Toda app Desktop/Web Koder expõe KoderUIStylePicker em Settings,
consumindo do enum KoderUIStyle do koder_kit v0.6.0+.
---
Audit script ui-style-audit.sh:
#!/usr/bin/env bash
# Verifica que módulo $1 importa KoderUIStylePicker e renderiza-o em alguma
# Settings page.
MODULE="$1"
if grep -rq "KoderUIStylePicker" "$MODULE/lib/" 2>/dev/null; then
echo '{"applied":[],"deferred":[],"errors":[]}'
exit 0
fi
echo '{"applied":[{"action":"missing-ui-style-picker","module":"'"$MODULE"'"}]}'
exit 1
Engine
koder-spec-audit (binário Go a criar em ETAPA 1.5):
1. Walk meta/docs/stack/{specs,policies}/**/*.kmd
2. Parse YAML frontmatter; skip if no `audit:` block
3. Resolve `applicable_to` to module list (expand glob, lookup coverage-matrix)
4. For each module: invoke `script` with module path as $1
5. Collect JSON outputs; aggregate by severity
6. Output consolidated report (json or text)
7. Exit:
- 0 if no hard severity drifts
- 1 if any hard severity drift
- 2 if any script errored
Subcomandos do /k-audit (a criar em ETAPA 1.6):
/k-audit # full sweep (todas specs/policies × todos módulos)
/k-audit specs # só severity=hard de specs/
/k-audit policies # só severity=advisory de policies/
/k-audit <module> # full sweep, módulo específico
/k-audit --spec=<glob> # filtra por glob de spec
Anti-patterns
Don't:
- Hardcodar lista de specs no comando — toda nova spec deveria ser auto-descoberta via frontmatter
- Misturar audit logic com declarations —
applicable_toé declarativo; lógica imperativa fica no script - Skipping o
severity— campo obrigatório; sem ele não dá pra distinguir "bloqueia commit" de "só reporta"
Do:
- Toda spec/policy nova ganha
audit:block — mesmo que script ainda não esteja escrito (pode ser stub que retorna pass) - Audit scripts ficam ao lado do
.kmd— descoberta por convenção - Severity reflete a natureza — spec testável = hard; princípio = advisory
Relação com policies/stack-principles.kmd
- Specs (severity=hard) ↔ rules deterministic, conformance testável
- Policies (severity=advisory) ↔ princípios, julgamento,
conflicts_with
Esta separação é estrutural (ver §3 de policies/stack-principles.kmd)
e refletida na semântica de severity.
Origem
Convenção definida durante a sessão de 2026-05-01 documentada em
projects/koder-stack/backlog/pending/101-stack-framework-ui-styles-settings-spec-audit.md,
ETAPA 1.4. Pivot do framework koder-spec-audit (ETAPA 1.5).
Referências
policies/stack-principles.kmdpolicies/code-first.kmdcommands/k-audit.md