@luanpdd/kit-mcp 1.10.0 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/gates/ai-prompt-stability.md +120 -0
- package/gates/legacy-refactor-safety.md +178 -0
- package/gates/observability-coverage.md +151 -0
- package/gates/release-pipeline-policy.md +132 -0
- package/kit/COMANDOS.md +15 -0
- package/kit/agents/ai-mutation-tester.md +298 -0
- package/kit/agents/cascading-failures-auditor.md +306 -0
- package/kit/agents/executor.md +13 -0
- package/kit/agents/legacy-characterizer.md +378 -0
- package/kit/agents/load-shedding-instrumenter.md +297 -0
- package/kit/agents/observability-coverage-auditor.md +325 -0
- package/kit/agents/omm-auditor.md +47 -0
- package/kit/agents/payload-capture-instrumenter.md +283 -0
- package/kit/agents/planner.md +29 -0
- package/kit/agents/prr-conductor.md +8 -0
- package/kit/agents/refactor-safety-auditor.md +414 -0
- package/kit/agents/release-pipeline-auditor.md +360 -0
- package/kit/agents/seam-finder.md +367 -0
- package/kit/agents/shotgun-surgery-detector.md +359 -0
- package/kit/agents/storytelling-analyst.md +309 -0
- package/kit/agents/supabase-edge-fn-writer.md +12 -0
- package/kit/agents/verifier.md +30 -0
- package/kit/commands/auditar-cascading.md +111 -0
- package/kit/commands/auditar-marco.md +44 -1
- package/kit/commands/auditar-observabilidade-cobertura.md +183 -0
- package/kit/commands/auditar-refactor.md +219 -0
- package/kit/commands/auditar-release.md +109 -0
- package/kit/commands/capturar-payloads.md +193 -0
- package/kit/commands/caracterizar-prompt.md +195 -0
- package/kit/commands/caracterizar.md +212 -0
- package/kit/commands/concluir-marco.md +41 -1
- package/kit/commands/detectar-duplicacao.md +197 -0
- package/kit/commands/discutir-fase.md +41 -0
- package/kit/commands/encontrar-seams.md +136 -0
- package/kit/commands/forense.md +40 -1
- package/kit/commands/legacy.md +263 -0
- package/kit/commands/load-shedding.md +117 -0
- package/kit/commands/observabilidade.md +2 -0
- package/kit/commands/refactor-seguro.md +321 -0
- package/kit/commands/sre.md +3 -0
- package/kit/commands/storytelling.md +179 -0
- package/kit/skills/_shared-legacy/glossary.md +389 -0
- package/kit/skills/_shared-sre/glossary.md +139 -0
- package/kit/skills/ai-prompt-characterization/SKILL.md +335 -0
- package/kit/skills/cascading-failures/SKILL.md +307 -0
- package/kit/skills/four-golden-signals/SKILL.md +17 -0
- package/kit/skills/hermetic-builds/SKILL.md +323 -0
- package/kit/skills/legacy-api-only-applications/SKILL.md +358 -0
- package/kit/skills/legacy-characterization-tests/SKILL.md +330 -0
- package/kit/skills/legacy-effect-analysis/SKILL.md +331 -0
- package/kit/skills/legacy-extract-class/SKILL.md +203 -0
- package/kit/skills/legacy-monster-methods/SKILL.md +444 -0
- package/kit/skills/legacy-programming-by-difference/SKILL.md +252 -0
- package/kit/skills/legacy-seams-and-test-harness/SKILL.md +460 -0
- package/kit/skills/legacy-shotgun-surgery/SKILL.md +286 -0
- package/kit/skills/legacy-sprout-wrap-techniques/SKILL.md +434 -0
- package/kit/skills/legacy-storytelling-naked-crc/SKILL.md +270 -0
- package/kit/skills/llm-as-dependency/SKILL.md +436 -0
- package/kit/skills/load-shedding-graceful-degradation/SKILL.md +396 -0
- package/kit/skills/pre-refactor-characterization/SKILL.md +421 -0
- package/kit/skills/release-engineering/SKILL.md +367 -0
- package/kit/skills/retry-strategies/SKILL.md +372 -0
- package/package.json +2 -2
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: ai-prompt-stability
|
|
3
|
+
stage: pre-execute
|
|
4
|
+
blocking: false
|
|
5
|
+
description: Valida que prompts/tools LLM em produção (qualquer arquivo em `prompts/` ou referenciado por código de produção como prompt) têm characterization tests linkados. Skip se projeto não usa LLM. Opt-in via workflow.ai_prompt_gate.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# AI prompt stability gate
|
|
9
|
+
|
|
10
|
+
**When to run:** pre-execute (consultive default; blocking se `workflow.ai_prompt_gate=true`).
|
|
11
|
+
|
|
12
|
+
**Skill canônica:** [`ai-prompt-characterization`](../kit/skills/ai-prompt-characterization/SKILL.md)
|
|
13
|
+
|
|
14
|
+
**Agent invocado:** [`legacy-characterizer`](../kit/agents/legacy-characterizer.md) (modo prompt)
|
|
15
|
+
|
|
16
|
+
## Check
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
#!/usr/bin/env bash
|
|
20
|
+
# PT-BR: validar que prompts em prod têm characterization tests
|
|
21
|
+
set -e
|
|
22
|
+
|
|
23
|
+
# detectar prompts em prod (heurística — paths canônicos)
|
|
24
|
+
PROMPT_FILES=""
|
|
25
|
+
for d in prompts src/prompts supabase/functions/*/prompts; do
|
|
26
|
+
[ -d "$d" ] && PROMPT_FILES="$PROMPT_FILES $(find "$d" -type f \( -name "*.md" -o -name "*.txt" -o -name "*.prompt" \) 2>/dev/null)"
|
|
27
|
+
done
|
|
28
|
+
|
|
29
|
+
if [ -z "$PROMPT_FILES" ]; then
|
|
30
|
+
echo "INFO: nenhum prompt em prod detectado — gate skip."
|
|
31
|
+
exit 0
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
# detectar gate mode
|
|
35
|
+
GATE_BLOCKING=false
|
|
36
|
+
if [ -f ".planning/config.json" ] && command -v jq >/dev/null; then
|
|
37
|
+
CFG=$(jq -r '.workflow.ai_prompt_gate // empty' .planning/config.json 2>/dev/null)
|
|
38
|
+
[ "$CFG" = "true" ] && GATE_BLOCKING=true
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
# para cada prompt, verificar characterization tests
|
|
42
|
+
PROMPTS_OK=()
|
|
43
|
+
PROMPTS_MISSING=()
|
|
44
|
+
|
|
45
|
+
for prompt in $PROMPT_FILES; do
|
|
46
|
+
STEM=$(basename "$prompt" | sed 's/\.[^.]*$//')
|
|
47
|
+
HAS_CHAR=false
|
|
48
|
+
for chardir in tests/characterization/prompts test/characterization/prompts __tests__/characterization/prompts; do
|
|
49
|
+
if find "$chardir" -path "*${STEM}*" 2>/dev/null | head -1 | grep -q . ; then
|
|
50
|
+
HAS_CHAR=true
|
|
51
|
+
break
|
|
52
|
+
fi
|
|
53
|
+
done
|
|
54
|
+
|
|
55
|
+
if [ "$HAS_CHAR" = "true" ]; then
|
|
56
|
+
PROMPTS_OK+=("$prompt")
|
|
57
|
+
else
|
|
58
|
+
LINES=$(wc -l < "$prompt" 2>/dev/null | tr -d ' ')
|
|
59
|
+
if [ "${LINES:-0}" -gt 50 ]; then # threshold: prompts > 50 linhas requerem char
|
|
60
|
+
PROMPTS_MISSING+=("$prompt (lines=$LINES)")
|
|
61
|
+
fi
|
|
62
|
+
fi
|
|
63
|
+
done
|
|
64
|
+
|
|
65
|
+
if [ ${#PROMPTS_MISSING[@]} -eq 0 ]; then
|
|
66
|
+
echo "✓ ai-prompt-stability — todos os prompts > 50 linhas têm characterization tests."
|
|
67
|
+
exit 0
|
|
68
|
+
fi
|
|
69
|
+
|
|
70
|
+
echo ""
|
|
71
|
+
echo "⚠ ai-prompt-stability — prompts sem characterization detectados:"
|
|
72
|
+
echo ""
|
|
73
|
+
for p in "${PROMPTS_MISSING[@]}"; do
|
|
74
|
+
echo " - $p"
|
|
75
|
+
done
|
|
76
|
+
echo ""
|
|
77
|
+
echo "Skill canônica: kit/skills/ai-prompt-characterization/SKILL.md"
|
|
78
|
+
echo ""
|
|
79
|
+
echo "Caminhos para resolver:"
|
|
80
|
+
echo " /caracterizar-prompt <prompt-file> (gera characterization tests)"
|
|
81
|
+
echo " /caracterizar-prompt <prompt> --num-intents 5 (5 intents canônicas)"
|
|
82
|
+
echo ""
|
|
83
|
+
|
|
84
|
+
if [ "$GATE_BLOCKING" = "true" ]; then
|
|
85
|
+
echo "MODE: blocking (workflow.ai_prompt_gate=true)"
|
|
86
|
+
echo "Resolve antes de prosseguir."
|
|
87
|
+
exit 1
|
|
88
|
+
else
|
|
89
|
+
echo "MODE: consultive (warning apenas)"
|
|
90
|
+
echo "Para tornar blocking: setar workflow.ai_prompt_gate=true em .planning/config.json"
|
|
91
|
+
exit 0
|
|
92
|
+
fi
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Configuração
|
|
96
|
+
|
|
97
|
+
```json
|
|
98
|
+
{
|
|
99
|
+
"workflow": {
|
|
100
|
+
"ai_prompt_gate": false,
|
|
101
|
+
"ai_prompt_min_lines": 50,
|
|
102
|
+
"ai_prompt_paths": ["prompts/**", "src/prompts/**", "supabase/functions/*/prompts/**"]
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**Default:** `ai_prompt_gate` = false (consultive). Promove para blocking se projeto tem ≥ 5 prompts em prod.
|
|
108
|
+
|
|
109
|
+
## Quando NÃO rodar
|
|
110
|
+
|
|
111
|
+
- Projeto não usa LLM em produção
|
|
112
|
+
- Prompts são apenas para dev tooling (não prod)
|
|
113
|
+
- Prompts < 50 linhas (threshold default)
|
|
114
|
+
|
|
115
|
+
## Ver também
|
|
116
|
+
|
|
117
|
+
- [`ai-prompt-characterization`](../kit/skills/ai-prompt-characterization/SKILL.md) — knowledge base
|
|
118
|
+
- [`legacy-characterization-tests`](../kit/skills/legacy-characterization-tests/SKILL.md) — characterization clássico
|
|
119
|
+
- [`legacy-refactor-safety`](./legacy-refactor-safety.md) — gate análogo para refactor de código
|
|
120
|
+
- [`llm-as-dependency`](../kit/skills/llm-as-dependency/SKILL.md) — fakear LLM em business logic tests
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: legacy-refactor-safety
|
|
3
|
+
stage: pre-execute
|
|
4
|
+
blocking: false
|
|
5
|
+
description: Valida que tasks com kind=refactor em arquivos > 500 linhas OU com contrato externo têm characterization tests linkados. Skip se fase só toca markdown OR fase é greenfield. Opt-in via workflow.legacy_refactor_gate_blocking=true.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Legacy refactor safety gate
|
|
9
|
+
|
|
10
|
+
**When to run:** pre-execute (consultive por default; blocking se `workflow.legacy_refactor_gate_blocking=true` E `omm.capacidade_1_resilience >= 3`).
|
|
11
|
+
|
|
12
|
+
**Skill canônica:** [`pre-refactor-characterization`](../kit/skills/pre-refactor-characterization/SKILL.md)
|
|
13
|
+
|
|
14
|
+
**Agent invocado:** [`refactor-safety-auditor`](../kit/agents/refactor-safety-auditor.md)
|
|
15
|
+
|
|
16
|
+
## Check
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
#!/usr/bin/env bash
|
|
20
|
+
# PT-BR: validar que tasks com kind=refactor em arquivos arriscados têm safety net.
|
|
21
|
+
# Estratégia: descobrir tasks da fase atual, identificar refactor + arquivos flagged,
|
|
22
|
+
# verificar characterization tests linkados, gerar warning ou block conforme mode.
|
|
23
|
+
# Bash 3.2-portable (macOS default).
|
|
24
|
+
set -e
|
|
25
|
+
|
|
26
|
+
# PT-BR: identificar fase atual via STATE.md
|
|
27
|
+
STATE_FILE=".planning/STATE.md"
|
|
28
|
+
CURRENT_PHASE=""
|
|
29
|
+
if [ -f "$STATE_FILE" ]; then
|
|
30
|
+
CURRENT_PHASE=$(grep -E "^Fase:" "$STATE_FILE" 2>/dev/null | head -1 | sed -E 's/^Fase: *([0-9]+).*/\1/')
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
if [ -z "$CURRENT_PHASE" ]; then
|
|
34
|
+
echo "INFO: nenhuma fase ativa — gate skip."
|
|
35
|
+
exit 0
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
PHASE_DIR=".planning/phases/phase-${CURRENT_PHASE}"
|
|
39
|
+
[ ! -d "$PHASE_DIR" ] && exit 0
|
|
40
|
+
|
|
41
|
+
# PT-BR: ler config para mode
|
|
42
|
+
GATE_BLOCKING=false
|
|
43
|
+
if [ -f ".planning/config.json" ] && command -v jq >/dev/null; then
|
|
44
|
+
CFG=$(jq -r '.workflow.legacy_refactor_gate_blocking // empty' .planning/config.json 2>/dev/null)
|
|
45
|
+
[ "$CFG" = "true" ] && GATE_BLOCKING=true
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
# PT-BR: ler omm — Capacidade 1 (Resilience) calibra mode default
|
|
49
|
+
if [ "$GATE_BLOCKING" = "false" ] && [ -f ".planning/OMM-REPORT.md" ]; then
|
|
50
|
+
OMM_RES=$(grep -oE 'Capacidade 1.*Resilience.*[0-9]/5' .planning/OMM-REPORT.md 2>/dev/null \
|
|
51
|
+
| grep -oE '[0-9]/5' | head -1 | sed 's|/5||')
|
|
52
|
+
if [ -n "$OMM_RES" ] && [ "$OMM_RES" -ge 3 ]; then
|
|
53
|
+
GATE_BLOCKING=true
|
|
54
|
+
fi
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
# PT-BR: identificar PLAN.md da fase atual
|
|
58
|
+
PLAN_FILES=$(find "$PHASE_DIR" -name "PLAN.md" 2>/dev/null)
|
|
59
|
+
|
|
60
|
+
REFACTOR_TASKS_RISKY=()
|
|
61
|
+
REFACTOR_TASKS_OK=()
|
|
62
|
+
TOTAL_REFACTOR=0
|
|
63
|
+
|
|
64
|
+
for plan_file in $PLAN_FILES; do
|
|
65
|
+
# PT-BR: detectar tasks com kind=refactor (heurística — frase canônica)
|
|
66
|
+
if grep -qiE "(refactor|refator|extract method|extract class|move method|reorganizar|limpar)" "$plan_file"; then
|
|
67
|
+
# extrair arquivos mencionados em tasks de refactor
|
|
68
|
+
AFFECTED_FILES=$(grep -oE "(src|lib|app|supabase|tests)/[a-zA-Z0-9_./-]+\.(ts|tsx|js|jsx|mjs|py|java|go|rb|cs|rs|cpp|c|h)" "$plan_file" 2>/dev/null | sort -u)
|
|
69
|
+
|
|
70
|
+
for f in $AFFECTED_FILES; do
|
|
71
|
+
[ ! -f "$f" ] && continue
|
|
72
|
+
|
|
73
|
+
# PT-BR: critérios de risco
|
|
74
|
+
LINES=$(wc -l < "$f" 2>/dev/null | tr -d ' ')
|
|
75
|
+
EXTERNAL=false
|
|
76
|
+
if echo "$f" | grep -qE "(supabase/functions|src/api|/handlers/webhooks|pages/api|integrations)"; then
|
|
77
|
+
EXTERNAL=true
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
RISK_HIGH=false
|
|
81
|
+
[ "${LINES:-0}" -gt 500 ] && RISK_HIGH=true
|
|
82
|
+
[ "$EXTERNAL" = "true" ] && RISK_HIGH=true
|
|
83
|
+
|
|
84
|
+
if [ "$RISK_HIGH" = "true" ]; then
|
|
85
|
+
TOTAL_REFACTOR=$((TOTAL_REFACTOR + 1))
|
|
86
|
+
|
|
87
|
+
# PT-BR: verificar characterization tests linkados
|
|
88
|
+
STEM=$(basename "$f" | sed 's/\.[^.]*$//')
|
|
89
|
+
HAS_CHAR=false
|
|
90
|
+
for chardir in tests test __tests__; do
|
|
91
|
+
if find "$chardir" -path "*characterization*$STEM*" 2>/dev/null | head -1 | grep -q . ; then
|
|
92
|
+
HAS_CHAR=true
|
|
93
|
+
break
|
|
94
|
+
fi
|
|
95
|
+
done
|
|
96
|
+
|
|
97
|
+
if [ "$HAS_CHAR" = "true" ]; then
|
|
98
|
+
REFACTOR_TASKS_OK+=("$f")
|
|
99
|
+
else
|
|
100
|
+
REFACTOR_TASKS_RISKY+=("$f (lines=$LINES, external=$EXTERNAL)")
|
|
101
|
+
fi
|
|
102
|
+
fi
|
|
103
|
+
done
|
|
104
|
+
fi
|
|
105
|
+
done
|
|
106
|
+
|
|
107
|
+
# PT-BR: relatório
|
|
108
|
+
if [ ${#REFACTOR_TASKS_RISKY[@]} -eq 0 ]; then
|
|
109
|
+
echo "✓ legacy-refactor-safety — sem refactors arriscados sem characterization."
|
|
110
|
+
if [ ${#REFACTOR_TASKS_OK[@]} -gt 0 ]; then
|
|
111
|
+
echo " ${#REFACTOR_TASKS_OK[@]} refactor(s) com characterization linkados."
|
|
112
|
+
fi
|
|
113
|
+
exit 0
|
|
114
|
+
fi
|
|
115
|
+
|
|
116
|
+
# PT-BR: há refactors arriscados sem char
|
|
117
|
+
echo ""
|
|
118
|
+
echo "⚠ legacy-refactor-safety — refactor(s) sem characterization detectado(s):"
|
|
119
|
+
echo ""
|
|
120
|
+
for item in "${REFACTOR_TASKS_RISKY[@]}"; do
|
|
121
|
+
echo " - $item"
|
|
122
|
+
done
|
|
123
|
+
echo ""
|
|
124
|
+
echo "Skill canônica: kit/skills/pre-refactor-characterization/SKILL.md"
|
|
125
|
+
echo ""
|
|
126
|
+
echo "Caminhos para resolver:"
|
|
127
|
+
echo " 1. /caracterizar <file> (full chain — preferido)"
|
|
128
|
+
echo " 2. /refactor-seguro --mode=sprout <file> (não toca legado, ADICIONA via sprout)"
|
|
129
|
+
echo " 3. /refactor-seguro --mode=safe-extract <file> (apenas refactor mecânico)"
|
|
130
|
+
echo " 4. /refactor-seguro --mode=override --ticket REQ-N --reason \"...\" (último recurso)"
|
|
131
|
+
echo ""
|
|
132
|
+
|
|
133
|
+
if [ "$GATE_BLOCKING" = "true" ]; then
|
|
134
|
+
echo "MODE: blocking (workflow.legacy_refactor_gate_blocking=true OR OMM Capacidade 1 ≥ 3)"
|
|
135
|
+
echo "Resolve antes de prosseguir com /executar-fase."
|
|
136
|
+
exit 1
|
|
137
|
+
else
|
|
138
|
+
echo "MODE: consultive (warning apenas)"
|
|
139
|
+
echo "Para tornar blocking: setar workflow.legacy_refactor_gate_blocking=true em .planning/config.json"
|
|
140
|
+
exit 0
|
|
141
|
+
fi
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Configuração
|
|
145
|
+
|
|
146
|
+
```json
|
|
147
|
+
// .planning/config.json
|
|
148
|
+
{
|
|
149
|
+
"workflow": {
|
|
150
|
+
"legacy_refactor_gate_blocking": true,
|
|
151
|
+
"legacy_refactor_min_lines": 500,
|
|
152
|
+
"legacy_refactor_external_paths": [
|
|
153
|
+
"supabase/functions/**",
|
|
154
|
+
"src/api/**",
|
|
155
|
+
"src/handlers/webhooks/**",
|
|
156
|
+
"pages/api/**"
|
|
157
|
+
]
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**Default:** `legacy_refactor_gate_blocking` = false (consultive). Auto-promove para `true` se `omm-auditor` (v1.9) reportar Capacidade 1 (Resilience) ≥ 3 — sinal de que projeto tem maturity de safety.
|
|
163
|
+
|
|
164
|
+
## Quando NÃO rodar
|
|
165
|
+
|
|
166
|
+
- Fase só toca markdown/docs — sem código a refactor
|
|
167
|
+
- Projeto < 1 mês de idade — código novo não é "legacy" no sentido Feathers
|
|
168
|
+
- Projeto sem `omm-auditor` rodado E sem flag explícita — skip silencioso (consultive)
|
|
169
|
+
- Tasks são `bug-fix` ou `feature` (não refactor) — gate só roda em refactor
|
|
170
|
+
|
|
171
|
+
## Ver também
|
|
172
|
+
|
|
173
|
+
- [`pre-refactor-characterization`](../kit/skills/pre-refactor-characterization/SKILL.md) — knowledge base do gate
|
|
174
|
+
- [`refactor-safety-auditor`](../kit/agents/refactor-safety-auditor.md) — agent invocado em runtime
|
|
175
|
+
- [`legacy-characterizer`](../kit/agents/legacy-characterizer.md) — agent que gera safety net
|
|
176
|
+
- [`golden-signals-coverage`](./golden-signals-coverage.md) — gate análogo da Suíte SRE
|
|
177
|
+
- [`prr-checklist-coverage`](./prr-checklist-coverage.md) — gate análogo da Suíte SRE para PRR
|
|
178
|
+
- [`omm-no-regression`](./omm-no-regression.md) — gate análogo da Suíte Observabilidade para OMM
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: observability-coverage
|
|
3
|
+
stage: pre-milestone-close
|
|
4
|
+
blocking: false
|
|
5
|
+
description: Valida que ≥ X% das Edge Functions têm 4 golden signals + SLO + burn alert + characterization. Default threshold 70%. Opt-in via workflow.observability_coverage_threshold.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Observability coverage gate (cross-suite)
|
|
9
|
+
|
|
10
|
+
**When to run:** pre-milestone-close (consultive default; blocking se `workflow.observability_coverage_threshold > 0`).
|
|
11
|
+
|
|
12
|
+
**Skills canônicas:** [`four-golden-signals`](../kit/skills/four-golden-signals/SKILL.md), [`event-based-slos`](../kit/skills/event-based-slos/SKILL.md), [`burn-rate-alerting`](../kit/skills/burn-rate-alerting/SKILL.md), [`legacy-characterization-tests`](../kit/skills/legacy-characterization-tests/SKILL.md)
|
|
13
|
+
|
|
14
|
+
**Agent invocado:** [`observability-coverage-auditor`](../kit/agents/observability-coverage-auditor.md)
|
|
15
|
+
|
|
16
|
+
## Check
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
#!/usr/bin/env bash
|
|
20
|
+
# PT-BR: validar cobertura cross-suite de Edge Functions
|
|
21
|
+
set -e
|
|
22
|
+
|
|
23
|
+
# threshold do gate
|
|
24
|
+
THRESHOLD=70
|
|
25
|
+
if [ -f ".planning/config.json" ] && command -v jq >/dev/null; then
|
|
26
|
+
CFG=$(jq -r '.workflow.observability_coverage_threshold // empty' .planning/config.json 2>/dev/null)
|
|
27
|
+
[ -n "$CFG" ] && [ "$CFG" != "null" ] && THRESHOLD=$CFG
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
# se threshold = 0, gate skip (opt-in)
|
|
31
|
+
if [ "$THRESHOLD" -eq 0 ]; then
|
|
32
|
+
echo "INFO: workflow.observability_coverage_threshold=0 — gate skip (opt-in não habilitado)."
|
|
33
|
+
exit 0
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
# enumerar Edge Functions
|
|
37
|
+
NUM_EDGE_FNS=$(find supabase/functions -mindepth 1 -maxdepth 1 -type d 2>/dev/null | wc -l)
|
|
38
|
+
if [ "$NUM_EDGE_FNS" -eq 0 ]; then
|
|
39
|
+
echo "INFO: nenhuma Edge Function detectada — gate skip."
|
|
40
|
+
exit 0
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
# contar Edge Functions cobertas em cada dimensão
|
|
44
|
+
COVERED_SIGNALS=0
|
|
45
|
+
COVERED_SLO=0
|
|
46
|
+
COVERED_BURN=0
|
|
47
|
+
COVERED_CHAR=0
|
|
48
|
+
|
|
49
|
+
for fn_dir in $(find supabase/functions -mindepth 1 -maxdepth 1 -type d 2>/dev/null); do
|
|
50
|
+
FN_NAME=$(basename "$fn_dir")
|
|
51
|
+
FN_FILE="$fn_dir/index.ts"
|
|
52
|
+
[ ! -f "$FN_FILE" ] && continue
|
|
53
|
+
|
|
54
|
+
# 4 golden signals
|
|
55
|
+
HAS_LATENCY=$(grep -qE "createHistogram|histogram.*ms|latency_histogram" "$FN_FILE" && echo true || echo false)
|
|
56
|
+
HAS_TRAFFIC=$(grep -qE "createCounter.*requests|http_requests_total|trafficCounter" "$FN_FILE" && echo true || echo false)
|
|
57
|
+
HAS_ERRORS=$(grep -qE "createCounter.*errors|http_errors_total|error_type" "$FN_FILE" && echo true || echo false)
|
|
58
|
+
HAS_SAT=$(grep -qE "createObservableGauge|connection_pool|queue_depth" "$FN_FILE" && echo true || echo false)
|
|
59
|
+
if [ "$HAS_LATENCY" = "true" ] && [ "$HAS_TRAFFIC" = "true" ] && [ "$HAS_ERRORS" = "true" ] && [ "$HAS_SAT" = "true" ]; then
|
|
60
|
+
COVERED_SIGNALS=$((COVERED_SIGNALS + 1))
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
# SLO
|
|
64
|
+
if [ -f ".planning/slos/$FN_NAME.md" ] || ([ -f ".planning/SLO.md" ] && grep -q "$FN_NAME" ".planning/SLO.md"); then
|
|
65
|
+
COVERED_SLO=$((COVERED_SLO + 1))
|
|
66
|
+
fi
|
|
67
|
+
|
|
68
|
+
# Burn alert
|
|
69
|
+
if grep -rq "$FN_NAME" .planning/burn-rate-alerts.md .planning/SLO.md 2>/dev/null; then
|
|
70
|
+
COVERED_BURN=$((COVERED_BURN + 1))
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
# Characterization
|
|
74
|
+
for chardir in tests/characterization test/characterization __tests__/characterization; do
|
|
75
|
+
if find "$chardir" -path "*$FN_NAME*" 2>/dev/null | head -1 | grep -q .; then
|
|
76
|
+
COVERED_CHAR=$((COVERED_CHAR + 1))
|
|
77
|
+
break
|
|
78
|
+
fi
|
|
79
|
+
done
|
|
80
|
+
done
|
|
81
|
+
|
|
82
|
+
# computar percentages
|
|
83
|
+
PCT_SIGNALS=$((COVERED_SIGNALS * 100 / NUM_EDGE_FNS))
|
|
84
|
+
PCT_SLO=$((COVERED_SLO * 100 / NUM_EDGE_FNS))
|
|
85
|
+
PCT_BURN=$((COVERED_BURN * 100 / NUM_EDGE_FNS))
|
|
86
|
+
PCT_CHAR=$((COVERED_CHAR * 100 / NUM_EDGE_FNS))
|
|
87
|
+
|
|
88
|
+
# avg
|
|
89
|
+
PCT_AVG=$(( (PCT_SIGNALS + PCT_SLO + PCT_BURN + PCT_CHAR) / 4 ))
|
|
90
|
+
|
|
91
|
+
echo ""
|
|
92
|
+
echo "observability-coverage gate — threshold: ${THRESHOLD}%"
|
|
93
|
+
echo ""
|
|
94
|
+
echo " 4 Golden Signals: ${COVERED_SIGNALS}/${NUM_EDGE_FNS} (${PCT_SIGNALS}%)"
|
|
95
|
+
echo " SLO definido: ${COVERED_SLO}/${NUM_EDGE_FNS} (${PCT_SLO}%)"
|
|
96
|
+
echo " Burn rate alert: ${COVERED_BURN}/${NUM_EDGE_FNS} (${PCT_BURN}%)"
|
|
97
|
+
echo " Characterization tests: ${COVERED_CHAR}/${NUM_EDGE_FNS} (${PCT_CHAR}%)"
|
|
98
|
+
echo ""
|
|
99
|
+
echo " Avg coverage: ${PCT_AVG}%"
|
|
100
|
+
echo ""
|
|
101
|
+
|
|
102
|
+
# decisão
|
|
103
|
+
if [ "$PCT_AVG" -ge "$THRESHOLD" ]; then
|
|
104
|
+
echo "✓ Avg ≥ threshold (${PCT_AVG}% ≥ ${THRESHOLD}%). Gate aprovado."
|
|
105
|
+
exit 0
|
|
106
|
+
fi
|
|
107
|
+
|
|
108
|
+
echo "⚠ Avg < threshold (${PCT_AVG}% < ${THRESHOLD}%)."
|
|
109
|
+
echo ""
|
|
110
|
+
echo "Próximas ações:"
|
|
111
|
+
echo " /auditar-observabilidade-cobertura (vê detalhes + top 5 críticas)"
|
|
112
|
+
echo " /golden-signals <fn> (instrumentar 4 signals)"
|
|
113
|
+
echo " /definir-slo <fn> (define SLO event-based)"
|
|
114
|
+
echo " /caracterizar <fn> (characterization tests)"
|
|
115
|
+
echo ""
|
|
116
|
+
|
|
117
|
+
# blocking se threshold > 0 e não atingido
|
|
118
|
+
if [ "$THRESHOLD" -gt 0 ]; then
|
|
119
|
+
exit 1
|
|
120
|
+
fi
|
|
121
|
+
|
|
122
|
+
exit 0
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Configuração
|
|
126
|
+
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"workflow": {
|
|
130
|
+
"observability_coverage_threshold": 70
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**Default:** `0` (skip — opt-in). Recomendação:
|
|
136
|
+
- Projetos < 6 meses: 50 (consultive)
|
|
137
|
+
- Projetos 6-12 meses: 70
|
|
138
|
+
- Projetos > 12 meses ou tier-1 production: 80+
|
|
139
|
+
|
|
140
|
+
## Quando NÃO rodar
|
|
141
|
+
|
|
142
|
+
- Projeto sem Edge Functions (puro frontend/backend stateless)
|
|
143
|
+
- Projeto recém-criado (< 1 mês) — distribuição de Edge Functions ainda imatura
|
|
144
|
+
- Greenfield onde Edge Functions estão sendo escritas em paralelo a milestones
|
|
145
|
+
|
|
146
|
+
## Ver também
|
|
147
|
+
|
|
148
|
+
- [`observability-coverage-auditor`](../kit/agents/observability-coverage-auditor.md) — agent canônico
|
|
149
|
+
- [`/auditar-observabilidade-cobertura`](../kit/commands/auditar-observabilidade-cobertura.md) — comando dedicado
|
|
150
|
+
- [`omm-no-regression`](./omm-no-regression.md) — gate análogo da Suíte Observabilidade
|
|
151
|
+
- [`golden-signals-coverage`](./golden-signals-coverage.md) — gate específico apenas para golden signals
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: release-pipeline-policy
|
|
3
|
+
stage: pre-milestone-close
|
|
4
|
+
blocking: false
|
|
5
|
+
description: Valida release pipeline scored ≥ X/30 (default 20 = ADEQUATE) em hermeticidade + reprodutibilidade + policy enforcement. Opt-in via workflow.complete_milestone_release_pipeline_gate. Cap 8 livro Google SRE.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Release pipeline policy gate
|
|
9
|
+
|
|
10
|
+
**When to run:** pre-milestone-close (consultive default; blocking se `workflow.complete_milestone_release_pipeline_gate=true`).
|
|
11
|
+
|
|
12
|
+
**Skill canônica:** [`release-engineering`](../kit/skills/release-engineering/SKILL.md) + [`hermetic-builds`](../kit/skills/hermetic-builds/SKILL.md)
|
|
13
|
+
|
|
14
|
+
**Agent invocado:** [`release-pipeline-auditor`](../kit/agents/release-pipeline-auditor.md)
|
|
15
|
+
|
|
16
|
+
## Check
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
#!/usr/bin/env bash
|
|
20
|
+
# PT-BR: validar release pipeline scored >= threshold
|
|
21
|
+
set -e
|
|
22
|
+
|
|
23
|
+
# threshold do gate
|
|
24
|
+
THRESHOLD=20 # default: ADEQUATE
|
|
25
|
+
GATE_BLOCKING=false
|
|
26
|
+
|
|
27
|
+
if [ -f ".planning/config.json" ] && command -v jq >/dev/null; then
|
|
28
|
+
CFG=$(jq -r '.workflow.complete_milestone_release_pipeline_gate // empty' .planning/config.json 2>/dev/null)
|
|
29
|
+
if [ "$CFG" = "true" ]; then
|
|
30
|
+
GATE_BLOCKING=true
|
|
31
|
+
fi
|
|
32
|
+
CFG_THRESH=$(jq -r '.workflow.release_pipeline_threshold // empty' .planning/config.json 2>/dev/null)
|
|
33
|
+
[ -n "$CFG_THRESH" ] && [ "$CFG_THRESH" != "null" ] && THRESHOLD=$CFG_THRESH
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
# se não opt-in, gate skip
|
|
37
|
+
if [ "$GATE_BLOCKING" = false ] && [ -z "$RELEASE_PIPELINE_POLICY_FORCE" ]; then
|
|
38
|
+
echo "INFO: release-pipeline-policy gate is opt-in (workflow.complete_milestone_release_pipeline_gate=false). Skip."
|
|
39
|
+
exit 0
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
# ler RELEASE-AUDIT.md OR delegar via Task se ausente/stale
|
|
43
|
+
AUDIT_FILE=".planning/RELEASE-AUDIT.md"
|
|
44
|
+
SCORE=""
|
|
45
|
+
|
|
46
|
+
if [ -f "$AUDIT_FILE" ]; then
|
|
47
|
+
# check se fresh (≤ 30 dias)
|
|
48
|
+
if [ "$(uname)" = "Darwin" ]; then
|
|
49
|
+
AUDIT_DATE=$(stat -f %m "$AUDIT_FILE")
|
|
50
|
+
else
|
|
51
|
+
AUDIT_DATE=$(stat -c %Y "$AUDIT_FILE")
|
|
52
|
+
fi
|
|
53
|
+
AGE_DAYS=$(( ($(date +%s) - AUDIT_DATE) / 86400 ))
|
|
54
|
+
|
|
55
|
+
if [ "$AGE_DAYS" -gt 30 ]; then
|
|
56
|
+
echo "⚠ RELEASE-AUDIT.md stale (${AGE_DAYS}d). Re-rodar /auditar-release antes de close."
|
|
57
|
+
[ "$GATE_BLOCKING" = true ] && exit 1
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
# parse score
|
|
61
|
+
SCORE=$(grep -oE "Score:\*\*\s*[0-9]+/30" "$AUDIT_FILE" | grep -oE "[0-9]+" | head -1)
|
|
62
|
+
fi
|
|
63
|
+
|
|
64
|
+
if [ -z "$SCORE" ]; then
|
|
65
|
+
echo "⚠ RELEASE-AUDIT.md ausente OR sem score parseável."
|
|
66
|
+
echo "Rode: /auditar-release (gera relatório fresh)"
|
|
67
|
+
[ "$GATE_BLOCKING" = true ] && exit 1
|
|
68
|
+
exit 0
|
|
69
|
+
fi
|
|
70
|
+
|
|
71
|
+
echo ""
|
|
72
|
+
echo "release-pipeline-policy gate — threshold: ${THRESHOLD}/30"
|
|
73
|
+
echo " RELEASE-AUDIT.md score: ${SCORE}/30"
|
|
74
|
+
echo ""
|
|
75
|
+
|
|
76
|
+
# decisão
|
|
77
|
+
if [ "$SCORE" -ge "$THRESHOLD" ]; then
|
|
78
|
+
if [ "$SCORE" -ge 25 ]; then
|
|
79
|
+
echo "✓ ROBUST (≥ 25/30) — milestone arquivável."
|
|
80
|
+
else
|
|
81
|
+
echo "✓ ADEQUATE (20-24) — milestone arquivável com warnings."
|
|
82
|
+
fi
|
|
83
|
+
exit 0
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
if [ "$SCORE" -lt 15 ]; then
|
|
87
|
+
echo "✗ BROKEN (< 15/30) — pipeline não pode ser fonte de verdade. ESCALAR."
|
|
88
|
+
elif [ "$SCORE" -lt 20 ]; then
|
|
89
|
+
echo "✗ FRAGILE (15-19/30) — gaps significativos."
|
|
90
|
+
fi
|
|
91
|
+
|
|
92
|
+
echo ""
|
|
93
|
+
echo "Próximas ações:"
|
|
94
|
+
echo " 1. Aplicar top 5 fixes do RELEASE-AUDIT.md"
|
|
95
|
+
echo " 2. Re-rodar /auditar-release"
|
|
96
|
+
echo " 3. Re-tentar /concluir-marco após score >= ${THRESHOLD}"
|
|
97
|
+
echo ""
|
|
98
|
+
|
|
99
|
+
[ "$GATE_BLOCKING" = true ] && exit 1
|
|
100
|
+
exit 0
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Configuração
|
|
104
|
+
|
|
105
|
+
```json
|
|
106
|
+
{
|
|
107
|
+
"workflow": {
|
|
108
|
+
"complete_milestone_release_pipeline_gate": false,
|
|
109
|
+
"release_pipeline_threshold": 20
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**Default:** `complete_milestone_release_pipeline_gate=false` (opt-in). Threshold 20 = ADEQUATE; promove para 25 (ROBUST) em projetos tier-1.
|
|
115
|
+
|
|
116
|
+
## Quando NÃO rodar
|
|
117
|
+
|
|
118
|
+
- Projeto < 6 meses (pipeline ainda imatura)
|
|
119
|
+
- Releases manuais (sem CI/CD complexo)
|
|
120
|
+
- Solo dev side project
|
|
121
|
+
- Projeto puramente experimental
|
|
122
|
+
|
|
123
|
+
## Ver também
|
|
124
|
+
|
|
125
|
+
- [`release-pipeline-auditor`](../kit/agents/release-pipeline-auditor.md) — agent canônico
|
|
126
|
+
- [`/auditar-release`](../kit/commands/auditar-release.md) — comando dedicado
|
|
127
|
+
- [`hermetic-builds`](../kit/skills/hermetic-builds/SKILL.md)
|
|
128
|
+
- [`release-engineering`](../kit/skills/release-engineering/SKILL.md)
|
|
129
|
+
- [`prr-checklist-coverage`](./prr-checklist-coverage.md) — gate análogo PRR (v1.10)
|
|
130
|
+
- [`legacy-refactor-safety`](./legacy-refactor-safety.md) — gate análogo Legacy (v1.12)
|
|
131
|
+
|
|
132
|
+
*Material-fonte: cap 8 livro Google SRE.*
|
package/kit/COMANDOS.md
CHANGED
|
@@ -112,6 +112,21 @@
|
|
|
112
112
|
| `/definir-perfil` | Altera o perfil de modelo para os agentes framework (quality/balanced/budget/inherit) |
|
|
113
113
|
| `/configuracoes` | Configura os toggles de workflow framework e perfil de modelo |
|
|
114
114
|
|
|
115
|
+
## Suíte Legacy Code (Feathers + modernizações IA/Supabase 2026)
|
|
116
|
+
|
|
117
|
+
| Comando | O que faz |
|
|
118
|
+
|---------|-----------|
|
|
119
|
+
| `/legacy <subcomando>` | Orquestrador único — dispatch para agents da suíte (10 subcomandos com sinônimos PT/EN) |
|
|
120
|
+
| `/caracterizar` | Gera characterization tests (cap 13) — golden snapshots cobrindo 7 grupos de equivalência |
|
|
121
|
+
| `/encontrar-seams` | Identifica seams (cap 25) e recomenda técnica de dependency-breaking |
|
|
122
|
+
| `/auditar-refactor` | Gate canônico — coleta evidências e retorna veredito GO/BLOCK/WARN/GO-OVERRIDE |
|
|
123
|
+
| `/refactor-seguro` | Chain canônico — seams → caracterizar → auditar → executar; modos full/sprout/safe-extract/override |
|
|
124
|
+
| `/capturar-payloads` | Instrumenta Edge Function Supabase para captura de payloads reais via mcp__supabase__get_logs (modernização) |
|
|
125
|
+
| `/caracterizar-prompt` | Characterization de prompts/tools LLM com temperature=0 + seed fixo (modernização IA) |
|
|
126
|
+
| `/storytelling` | IA gera mental model + naked CRC + extract candidates (cap 16-17 + modernização IA) |
|
|
127
|
+
| `/detectar-duplicacao` | Shotgun surgery cross-codebase via embeddings + jscpd (cap 21 + modernização IA) |
|
|
128
|
+
| `/auditar-observabilidade-cobertura` | Audit X/N Edge Functions com signals + SLO + burn alert + char (cross-suite) |
|
|
129
|
+
|
|
115
130
|
## Utilitários
|
|
116
131
|
|
|
117
132
|
| Comando | O que faz |
|