Audit Frontmatter
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.
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: "productsapp/{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.
*orms aceitas:*
| Form | Exemplo | Semântica |
|---|---|---|
| *lob de path* | "productsapp/{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 |
| *always`* | "always" |
aplica a Stack toda (ex.: policies/stack-principles.kmd) |
| *never`* | "never" |
spec não-auditável programaticamente (raríssimo) |
*ombinação:*múltiplas linhas em applicable_to são tratadas como *niã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.
*ipo do arquivo:*shell script (preferred), Python script, ou binário. Tem que ser executável.
*ontrato:*
#!/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: 2output_format (optional)
Default json per RFC001 §4 do `dev/kodertools. 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:
- "productsapp/{desktop,web}"
- "servicesapp/{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 1Engine
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 erroredSubcomandos 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 specAnti-patterns
*on't:*
- *ardcodar lista de specs no comando*— toda nova spec deveria ser
auto-descoberta via frontmatter
- *isturar audit logic com declarations*—
applicable_toédeclarativo; lógica imperativa fica no script
- *kipping o
severity*— campo obrigatório; sem ele não dá pradistinguir "bloqueia commit" de "só reporta"
*o:*
- *oda spec/policy nova ganha
audit:block*— mesmo que scriptainda não esteja escrito (pode ser stub que retorna pass)
- *udit scripts ficam ao lado do
.kmd*— descoberta por convenção - *everity reflete a natureza*— spec testável = hard; princípio
= advisory
Relação com policies/stack-principles.kmd
- *pecs (severity=hard)*↔ rules deterministic, conformance testável
- *olicies (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 20260501 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).