bigpowers 2.87.1 → 2.87.3

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.
@@ -0,0 +1,321 @@
1
+ # Validação Cruzada: Bigpowers vs. GSD (Get Shit Done)
2
+
3
+ **Data:** 2026-05-18
4
+ **Scope:** Comparar consolidação proposta com arquitetura de artefatos de GSD
5
+
6
+ ---
7
+
8
+ ## 1. Comparação de Estrutura
9
+
10
+ ### GSD (Get Shit Done)
11
+ ```
12
+ .planning/
13
+ ├── PROJECT.md ← Contexto do projeto (validado vs. em escopo)
14
+ ├── ROADMAP.md ← Fases + plans + success criteria
15
+ ├── STATE.md ← Estado atual (< 100 linhas)
16
+ ├── {phase}-{plan}-PLAN.md ← Planos individuais
17
+ └── todos/pending/ ← Ideias capturadas
18
+
19
+ templates/ ← 30+ templates
20
+ references/ ← 60+ docs de referência técnica
21
+ workflows/ ← 93+ workflows (comandos CLI)
22
+ ```
23
+
24
+ ### Bigpowers (Proposta de Consolidação)
25
+ ```
26
+ specs/
27
+ ├── STATE.md ← Estado atual (59 linhas) ✅
28
+ ├── RELEASE-PLAN.md ← Roadmap vivo ✅
29
+ ├── PLAN-v*.md ← Histórico → archive/ ✅
30
+ ├── archive/releases/ ← Novo: histórico consolidado
31
+ ├── CONTEXT.md, UBIQUITOUS_LANGUAGE.md, etc.
32
+ └── ...
33
+
34
+ SKILL-INDEX.md ← Novo: tabela canônica
35
+ README.md ← Simplificado
36
+ CONVENTIONS.md ← Existente
37
+ ```
38
+
39
+ ---
40
+
41
+ ## 2. Gap Analysis: O Que Falta em Bigpowers
42
+
43
+ ### 2.1 Falta: PROJECT.md (Contexto do Projeto)
44
+
45
+ **GSD tem:**
46
+ ```markdown
47
+ # PROJECT.md
48
+
49
+ ## What This Is
50
+ [Descrição atual do projeto]
51
+
52
+ ## Core Value
53
+ [Uma coisa que importa mais]
54
+
55
+ ## Requirements
56
+ - Validated (já enviado, comprovado)
57
+ - Active (em construção)
58
+ - Out of Scope (com razão do exclusão)
59
+
60
+ ## Context
61
+ [Background técnico e de usuário]
62
+
63
+ ## Constraints
64
+ [Limitações: stack, timeline, etc.]
65
+
66
+ ## Key Decisions
67
+ [Histórico de decisões significativas]
68
+ ```
69
+
70
+ **Bigpowers não tem equivalente.** Tem CLAUDE.md (comandos, stack, arquitetura), mas não tem:
71
+ - ❌ Requisitos (Validated/Active/Out of Scope)
72
+ - ❌ Core Value (a uma coisa que importa)
73
+ - ❌ Decisões significativas rastreadas
74
+ - ❌ Constraints formalizadas
75
+
76
+ **Recomendação:** Criar `specs/PROJECT.md` para bigpowers com:
77
+ - What This Is: "38 agent skills for spec-driven TDD by solo developers"
78
+ - Core Value: "Maintain quality (audit score) while scaling skill count"
79
+ - Active Requirements: Feature completeness, testing mandates, etc.
80
+ - Out of Scope: Domain-specific skills (scaffold-exercises), plugins, marketplace
81
+ - Key Decisions: verb-noun naming, local-first (sem GitHub issues), BMAD phases, etc.
82
+
83
+ ---
84
+
85
+ ### 2.2 ROADMAP.md vs. RELEASE-PLAN.md
86
+
87
+ **GSD usa ROADMAP.md:**
88
+ - Fases numeradas (1, 2, 3, ...)
89
+ - Decimal phases para inserts (2.1 = "critical fix inserted between 2 and 3")
90
+ - Success Criteria (observable behaviors)
91
+ - Plans count per phase
92
+ - Progress table com milestone column
93
+
94
+ **Bigpowers usa RELEASE-PLAN.md:**
95
+ - Releases (v1.11, v1.12, ...)
96
+ - WSJF scoring
97
+ - Status (✅, ⏳)
98
+ - Focus area (Benchmarks, Auditor, Karpathy, etc.)
99
+ - Detailed action items per release
100
+
101
+ **Análise:**
102
+ - ✅ RELEASE-PLAN.md é mais rico que ROADMAP (tem WSJF, status, detalhes)
103
+ - ✅ Ambas rastreiam progresso
104
+ - ⚠️ Bigpowers não tem "Success Criteria" formalizados (deveriam estar em STATE ou PROJECT)
105
+
106
+ **Recomendação:** Manter RELEASE-PLAN.md, mas adicionar "Success Criteria" por release:
107
+ ```markdown
108
+ ### v1.17.0 — Guardrails (WSJF 3.2) ⏳
109
+
110
+ **Success Criteria:**
111
+ - [ ] "Zoom-out mandate" implemented in plan-work as HARD-GATE
112
+ - [ ] Surgical changes checklist in audit-code passes 100% of tests
113
+ - [ ] CONVENTIONS.md explicitly forbids "touch unrelated code"
114
+ ```
115
+
116
+ ---
117
+
118
+ ### 2.3 Artefatos Intermediários (Templates)
119
+
120
+ **GSD tem 30+ templates:**
121
+ - AI-SPEC.md, DEBUG.md, VALIDATION.md
122
+ - discovery.md, research.md, spec.md
123
+ - planner-subagent-prompt.md
124
+ - continue-here.md
125
+
126
+ **Bigpowers tem:**
127
+ - Implícitos em cada skill (não há templates separados)
128
+ - Rely em CONVENTIONS.md
129
+
130
+ **Recomendação:** Criar `templates/` subdir em bigpowers:
131
+ ```
132
+ templates/
133
+ ├── spec.md (→ specs/PLAN.md output format)
134
+ ├── phase-discussion.md (→ output de elaborate-spec)
135
+ ├── diagnosis.md (→ output de investigate-bug)
136
+ └── ...
137
+ ```
138
+
139
+ ---
140
+
141
+ ### 2.4 Referências Técnicas (References)
142
+
143
+ **GSD tem 60+ references:**
144
+ - gates.md (quais gates bloquear, quais permitir)
145
+ - planner-antipatterns.md (o que não fazer)
146
+ - verification-patterns.md (como testar)
147
+ - thinking-models-*.md (modelos de pensamento por agente)
148
+ - tdd.md, executor-examples.md
149
+
150
+ **Bigpowers tem:**
151
+ - AUDIT.md (auditoria de cobertura de Clean Code)
152
+ - COMPARISON.md (comparação com superpowers, BMAD, etc.)
153
+ - Skills source em SKILL.md (inline docs)
154
+
155
+ **Recomendação:** Segregar em `references/`:
156
+ ```
157
+ references/
158
+ ├── clean-code-mapping.md (como cada skill implementa Clean Code)
159
+ ├── gates-and-guardrails.md (HARD-GATEs em cada skill)
160
+ ├── skill-antipatterns.md (o que não fazer em cada skill)
161
+ ├── bmad-lifecycle.md (phases BMAD detalhadas)
162
+ └── ...
163
+ ```
164
+
165
+ ---
166
+
167
+ ## 3. Validação: Minha Proposta vs. GSD
168
+
169
+ ### O Que Está Certo em Minha Proposta
170
+
171
+ ✅ **Hierarquia de artefatos**
172
+ - STATE → RELEASE-PLAN → SKILL-INDEX → README
173
+ - GSD faz: PROJECT → ROADMAP → STATE → PLAN
174
+ - Abordagens equivalentes, estilos diferentes
175
+
176
+ ✅ **Consolidação de redundância**
177
+ - Deletar PLAN.md (stale) ← mesma que GSD faria
178
+ - Arquivar PLAN-v*.md ← GSD collapsa em `<details>` tags
179
+ - Single skill index ← GSD não tem equivalent, é um win para bigpowers
180
+
181
+ ✅ **Nomes simples (verb-noun)**
182
+ - Bigpowers: `develop-tdd`, `validate-fix`, etc.
183
+ - GSD: `/gsd-new-project`, `/gsd-plan-phase`, etc. (verb-noun style)
184
+ - ✓ Bigpowers está bem aqui
185
+
186
+ ✅ **Clareza de fases (BMAD)**
187
+ - Bigpowers: Discover → Elaborate → Plan → Build → Sustain
188
+ - GSD: Phase 1, 2, 3, ... (fases numeradas)
189
+ - Ambas funcionam; BMAD é mais descritivo
190
+
191
+ ### O Que Está Incompleto em Minha Proposta
192
+
193
+ ❌ **Falta PROJECT.md**
194
+ - GSD começa aqui: "What This Is", "Core Value", "Requirements"
195
+ - Bigpowers tem CLAUDE.md, mas não `specs/PROJECT.md`
196
+ - **Ação:** Adicionar PROJECT.md como canônico de contexto do projeto
197
+
198
+ ❌ **Falta Success Criteria formalizados**
199
+ - GSD em ROADMAP: "Observable behaviors that must be TRUE"
200
+ - Bigpowers em RELEASE-PLAN: Apenas "Focus Area" e "Objective"
201
+ - **Ação:** Adicionar Success Criteria por release em RELEASE-PLAN.md
202
+
203
+ ❌ **Falta templates/ e references/**
204
+ - GSD segrega templates (30+) e references (60+)
205
+ - Bigpowers tem tudo inline em SKILL.md
206
+ - **Ação:** Opcional; se fizer, criar `templates/` e `references/` como em GSD
207
+
208
+ ❌ **Falta "Skill Antipatterns" ou "Gates"**
209
+ - GSD tem gates.md (quais gates bloquear)
210
+ - Bigpowers tem mandates em prose, não formalizados
211
+ - **Ação:** Criar `references/gates-and-guardrails.md`
212
+
213
+ ---
214
+
215
+ ## 4. Recomendação: Incorporar Melhores Práticas de GSD
216
+
217
+ ### Fase 1: Imediato (Incorporar em Análise/SKILL-INDEX)
218
+
219
+ - [ ] Criar `specs/PROJECT.md` com:
220
+ - What This Is
221
+ - Core Value
222
+ - Active Requirements
223
+ - Out of Scope
224
+ - Key Decisions (a tabela de ADRs existentes)
225
+
226
+ - [ ] Atualizar RELEASE-PLAN.md com Success Criteria por release
227
+
228
+ - [ ] Manter SKILL-INDEX.md como proposto (similar a nada em GSD, é um win único)
229
+
230
+ ### Fase 2: Médio Prazo (30 min de trabalho)
231
+
232
+ - [ ] Criar `templates/` com estruturas esperadas (spec.md, diagnosis.md, etc.)
233
+
234
+ - [ ] Criar `references/bmad-phases.md` (ciclo BMAD detalhado)
235
+
236
+ - [ ] Criar `references/gates-and-guardrails.md` (HARD-GATEs por skill)
237
+
238
+ ### Fase 3: Longo Prazo (Nice-to-Have)
239
+
240
+ - [ ] Criar `references/skill-antipatterns.md` (o que não fazer)
241
+
242
+ - [ ] Criar `references/clean-code-mapping.md` (como cada skill implementa Clean Code)
243
+
244
+ ---
245
+
246
+ ## 5. Tabela: Estrutura Final Recomendada
247
+
248
+ | Nível | Artefato | Propósito | GSD Equivalente |
249
+ |---|---|---|---|
250
+ | **Visão** | specs/PROJECT.md | Contexto, requisitos, decisões | PROJECT.md |
251
+ | **Roadmap** | specs/RELEASE-PLAN.md | Sequência de releases + success criteria | ROADMAP.md |
252
+ | **Estado** | specs/STATE.md | Posição atual (< 100 linhas) | STATE.md |
253
+ | **Skill Catalog** | SKILL-INDEX.md | Tabela canônica de 38 skills | (N/A em GSD) |
254
+ | **Templates** | templates/*.md | Estruturas esperadas | templates/ |
255
+ | **Referência** | references/*.md | Gates, antipatterns, ciclo BMAD | references/ |
256
+ | **Documentação** | README.md | Install, quickstart | README.md |
257
+ | **Convênios** | CONVENTIONS.md | Code, test, git, specs/ standards | CONVENTIONS.md |
258
+ | **Histórico** | specs/archive/releases/PLAN-v*.md | Planos completados | (Collapsed em ROADMAP) |
259
+
260
+ ---
261
+
262
+ ## 6. Validação Final: Aplicar ao Projeto Skills
263
+
264
+ **Antes (Atual):**
265
+ ```
266
+ PLAN.md (stale, 453 linhas)
267
+ ↓
268
+ specs/RELEASE-PLAN.md (vivo, 104 linhas)
269
+ ↓
270
+ specs/STATE.md (59 linhas) ✓
271
+ ↓
272
+ specs/PLAN-v*.md (16 arquivos, dispersos)
273
+ ↓
274
+ README.md (191 linhas, copia RELEASE-PLAN)
275
+ ```
276
+
277
+ **Depois (Proposto + GSD Best Practice):**
278
+ ```
279
+ specs/PROJECT.md (novo) ← Core Value, Requirements, Decisions
280
+ ↓
281
+ specs/RELEASE-PLAN.md (revisado) ← Roadmap + Success Criteria
282
+ ↓
283
+ specs/STATE.md (mantém) ← Current Position
284
+ ↓
285
+ SKILL-INDEX.md (novo) ← Tabela canônica
286
+ ↓
287
+ README.md (simplificado) ← Install, quickstart, link a SKILL-INDEX
288
+ ↓
289
+ templates/ (novo, opcional) ← Estruturas esperadas
290
+ references/ (novo, opcional) ← Gates, antipatterns, BMAD phases
291
+ ```
292
+
293
+ **Resultado:**
294
+ - ✅ Sem redundância entre PLAN.md, RELEASE-PLAN, README
295
+ - ✅ Hierarquia clara: PROJECT → RELEASE-PLAN → STATE → SKILL-INDEX
296
+ - ✅ Incorpora melhores práticas de GSD sem copiar excessivamente
297
+ - ✅ Nomes simples (verb-noun) mantidos
298
+ - ✅ Fases BMAD explícitas em PROJECT.md ou documento separado
299
+
300
+ ---
301
+
302
+ ## 7. Checklist Final
303
+
304
+ - [x] Minha análise identificou redundâncias corretas (PLAN.md, PLAN-v*.md, skill index)
305
+ - [x] Minha hierarquia proposta é consistente com GSD (STATE → ROADMAP → skills)
306
+ - [x] Faltou: PROJECT.md (contexto do projeto)
307
+ - [x] Faltou: Success Criteria formalizados
308
+ - [x] Faltou: templates/ e references/ (nice-to-have)
309
+ - [x] SKILL-INDEX.md é único valor adicionado vs. GSD (bom!)
310
+ - [x] Nomes simples e ciclo BMAD estão corretos
311
+ - [x] Recomendação: Incorporar PROJECT.md + Success Criteria antes de executar
312
+
313
+ ---
314
+
315
+ ## 8. Próximos Passos Imediatos
316
+
317
+ 1. ✅ Criar `specs/PROJECT.md` com estrutura de GSD
318
+ 2. ✅ Atualizar `specs/RELEASE-PLAN.md` com Success Criteria
319
+ 3. ✅ Finalmente: Deletar `PLAN.md`, arquivar `PLAN-v*.md`, simplificar README
320
+ 4. 📝 Opcional: Criar `templates/` e `references/` conforme GSD
321
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bigpowers",
3
- "version": "2.87.1",
3
+ "version": "2.87.3",
4
4
  "description": "73 agent skills synthesizing 17 years of software engineering discipline into a prescriptive methodology for solo developers",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -18,7 +18,7 @@ partition() {
18
18
  git -C "$ROOT" log --no-merges "$range" \
19
19
  --pretty=format:"%at%x1f%H%x1f%(trailers:key=${key},valueonly,separator=%x2C)" \
20
20
  | sort -n \
21
- | awk -F '\x1f' -v IDLE="$IDLE_SECONDS" -v PAD="$PAD_SECONDS" '
21
+ | awk -v FS="$(printf '\037')" -v IDLE="$IDLE_SECONDS" -v PAD="$PAD_SECONDS" '
22
22
  {
23
23
  ts = $1 + 0; story = $3
24
24
  gsub(/[[:space:]]/, "", story)
@@ -48,6 +48,9 @@ parse_frontmatter() {
48
48
  fi
49
49
  [ "$in_block" -ne 1 ] && continue
50
50
 
51
+ # Skip comment lines (e.g. # story: tags inside the frontmatter block)
52
+ [[ "$line" == \#* || "$line" == \<\!--* ]] && continue
53
+
51
54
  case "$line" in
52
55
  name:*)
53
56
  name="${line#name: }"
@@ -76,6 +79,8 @@ parse_frontmatter() {
76
79
  continue
77
80
  fi
78
81
  [ "$continued" -eq 0 ] && continue
82
+ # Skip comment lines (e.g. # story: tags inside the frontmatter block)
83
+ [[ "$line" == \#* || "$line" == \<\!--* ]] && continue
79
84
  # If next field starts (unindented key:), stop
80
85
  [[ "$line" =~ ^[a-zA-Z_]+: ]] && break
81
86
  desc="$desc $line"
@@ -103,7 +108,7 @@ parse_frontmatter_okf() {
103
108
  _PF_NAME=$(awk '/^---/{f++} f==1 && /^name:/{print; exit}' "$file" | sed 's/^name:[[:space:]]*//')
104
109
  _PF_MODEL=$(awk '/^---/{f++} f==1 && /^model:/{print; exit}' "$file" | sed 's/^model:[[:space:]]*//')
105
110
  _PF_EFFORT=$(awk '/^---/{f++} f==1 && /^effort:/{print; exit}' "$file" | sed 's/^effort:[[:space:]]*//')
106
- _PF_DESCRIPTION=$(awk '/^---/{f++; next} f==1 && /^description:/{p=1; sub(/^description:[[:space:]]*/,""); print; next} f==1 && p && /^[a-z]+:/{exit} f==1 && p{print}' "$file" \
111
+ _PF_DESCRIPTION=$(awk '/^---/{f++; next} f==1 && /^description:/{p=1; sub(/^description:[[:space:]]*/,""); print; next} f==1 && p && /^[a-z]+:/{exit} f==1 && p && !/^[[:space:]]*#/ && !/^[[:space:]]*<!--/{print}' "$file" \
107
112
  | tr -d '\n' \
108
113
  | sed -E 's/[[:space:]]+/ /g')
109
114
 
@@ -90,7 +90,7 @@ cmd_report() {
90
90
  }
91
91
 
92
92
  cmd_append() {
93
- local range="HEAD" key="$STORY_KEY" story="" bcps="" merged_at="" file="$ROOT/specs/metrics/cycle-times.yaml"
93
+ local range="HEAD" key="$STORY_KEY" story="" bcps="" bcp_plus="" merged_at="" file="$ROOT/specs/metrics/cycle-times.yaml"
94
94
  local telemetry="" # path to harness telemetry JSON (GSD-2/gsd-pi format, optional)
95
95
  while [ $# -gt 0 ]; do
96
96
  case "$1" in
@@ -143,6 +143,8 @@ cmd_append() {
143
143
  agent_compression="null"; agent_tool_calls="null"; agent_api_requests="null"
144
144
  agent_duration_ms="null"; agent_model="null"; agent_tier="null"
145
145
  agent_downgraded="null"; agent_skills="[]"
146
+ agent_tokens_in="null"; agent_tokens_out="null"
147
+ agent_tokens_cache_read="null"; agent_tokens_cache_write="null"
146
148
 
147
149
  if [ -n "$telemetry" ] && [ -f "$telemetry" ]; then
148
150
  # GSD-2/gsd-pi snapshotUnitMetrics JSON format:
@@ -79,7 +79,13 @@ ste_extract_prose() {
79
79
 
80
80
  ste_count_words() {
81
81
  # shellcheck disable=SC2207
82
- local words=($1)
82
+ local words
83
+ # BUG-2026-08-05-ste-glob-wordcount: ($1) globs each word — a bare ** (markdown
84
+ # bold opener) expands to every file in cwd and inflates the count. Disable
85
+ # pathname expansion; safe here because this function only runs inside $( ).
86
+ set -f
87
+ words=($1)
88
+ set +f
83
89
  echo "${#words[@]}"
84
90
  }
85
91
 
@@ -168,6 +174,14 @@ name: fixture-long
168
174
  description: Long sentence fixture.
169
175
  ---
170
176
  Run the full local green stack including compliance verification gates sync skills trace stories and catalog drift check before any forward implementation work on this repository.
177
+ EOF
178
+
179
+ cat > "$tmp/good-bold.md" <<'EOF'
180
+ ---
181
+ name: fixture-bold
182
+ description: Bold markdown list fixture (BUG-2026-08-05-ste-glob-wordcount).
183
+ ---
184
+ 1. **Check dependencies first.** DO inspect what your current dependencies already do before writing your own code.
171
185
  EOF
172
186
 
173
187
  local saved_strict=$STRICT saved_audit=$AUDIT
@@ -181,6 +195,13 @@ EOF
181
195
  return 1
182
196
  fi
183
197
 
198
+ VIOLATIONS=0
199
+ ste_audit_file "$tmp/good-bold.md"
200
+ if (( VIOLATIONS > 0 )); then
201
+ echo "SELF-TEST FAIL: bold-markdown fixture should pass (glob word-count bug, BUG-2026-08-05)" >&2
202
+ return 1
203
+ fi
204
+
184
205
  VIOLATIONS=0
185
206
  ste_audit_file "$tmp/bad-hedge.md"
186
207
  if (( VIOLATIONS == 0 )); then
@@ -1,5 +1,21 @@
1
1
  #!/usr/bin/env python3
2
- """Validate YAML frontmatter in all .pi/skills/*/SKILL.md files."""
2
+ """Validate YAML frontmatter in SKILL.md files (sources + generated .pi/skills).
3
+
4
+ Rules per file (sources and generated copies alike):
5
+
6
+ R1 file must start with the frontmatter delimiter '---' at byte 0.
7
+ pi (dist/utils/frontmatter.js) and the Agent Skills spec require the
8
+ opening delimiter to be the first characters of the file. Story tags
9
+ (`# story:` / `<!-- story: -->`) must live INSIDE the frontmatter block
10
+ as YAML comments, or below the closing delimiter — never above it,
11
+ or pi drops the skill as "description is required".
12
+ (story: BUG-2026-08-06-pi-drops-skills-frontmatter)
13
+ R2 frontmatter must parse as YAML (PyYAML or bundled simple_yaml).
14
+ R3 description must not embed 'model: sonnet' as literal text.
15
+
16
+ Exits 1 on any failure. Called by the sync-skills.sh post-generation guard
17
+ and by scripts/test-setup-no-pyyaml.sh.
18
+ """
3
19
  import glob
4
20
  import sys
5
21
  import os
@@ -17,64 +33,99 @@ except ModuleNotFoundError:
17
33
  from simple_yaml import parse_simple_yaml
18
34
  _load_yaml = parse_simple_yaml
19
35
 
20
- SKILLS_DIR = ".pi/skills"
21
- files = sorted(glob.glob(f"{SKILLS_DIR}/*/SKILL.md"))
36
+ # Source of truth (skills/*/SKILL.md) and the pi-distributed copy (.pi/skills).
37
+ SKILL_ROOTS = ["skills", ".pi/skills"]
38
+
39
+
40
+ def validate_tree(root):
41
+ """Return (passed, delimiter_failures, parse_failures, semantic_failures)."""
42
+ files = sorted(glob.glob(os.path.join(root, "*/SKILL.md")))
43
+ parse_failures = []
44
+ semantic_failures = []
45
+ delimiter_failures = []
46
+ passed = []
47
+
48
+ for path in files:
49
+ skill_name = os.path.basename(os.path.dirname(path))
50
+ with open(path) as f:
51
+ content = f.read()
52
+
53
+ # R1 — pi's frontmatter gate: opening delimiter must be at byte 0.
54
+ if not content.startswith("---"):
55
+ delimiter_failures.append((skill_name, "file must start with '---' (story tags belong inside the frontmatter block or below it)"))
56
+ continue
22
57
 
23
- parse_failures = []
24
- semantic_failures = []
25
- passed = []
58
+ parts = content.split("---", 2)
59
+ if len(parts) < 3:
60
+ parse_failures.append((skill_name, "missing frontmatter delimiters"))
61
+ continue
26
62
 
27
- for path in files:
28
- skill_name = os.path.basename(os.path.dirname(path))
29
- with open(path) as f:
30
- content = f.read()
63
+ frontmatter = parts[1]
31
64
 
32
- parts = content.split("---", 2)
33
- if len(parts) < 3:
34
- parse_failures.append((skill_name, "missing frontmatter delimiters"))
35
- continue
65
+ try:
66
+ data = _load_yaml(frontmatter)
67
+ except Exception as e:
68
+ parse_failures.append((skill_name, str(e).split("\n")[0]))
69
+ continue
36
70
 
37
- frontmatter = parts[1]
71
+ if data is None:
72
+ parse_failures.append((skill_name, "empty frontmatter"))
73
+ continue
38
74
 
39
- try:
40
- data = _load_yaml(frontmatter)
41
- except Exception as e:
42
- parse_failures.append((skill_name, str(e).split("\n")[0]))
43
- continue
75
+ # R3 — semantic check: model hint embedded in description
76
+ desc = data.get("description", "")
77
+ if desc and "model: sonnet" in desc:
78
+ semantic_failures.append(skill_name)
44
79
 
45
- if data is None:
46
- parse_failures.append((skill_name, "empty frontmatter"))
47
- continue
80
+ passed.append(skill_name)
48
81
 
49
- # Semantic check: model hint embedded in description
50
- desc = data.get("description", "")
51
- if desc and "model: sonnet" in desc:
52
- semantic_failures.append(skill_name)
82
+ return passed, delimiter_failures, parse_failures, semantic_failures
53
83
 
54
- passed.append(skill_name)
55
84
 
56
- # Report
57
- print(f"Total SKILL.md files: {len(files)}")
58
- print(f"Parse OK: {len(passed)}")
59
- print(f"Parse FAIL: {len(parse_failures)}")
60
- print(f"Semantic issues (model in desc): {len(semantic_failures)}")
85
+ all_passed = []
86
+ all_delimiter = []
87
+ all_parse = []
88
+ all_semantic = []
89
+
90
+ for root in SKILL_ROOTS:
91
+ passed, delimiter_failures, parse_failures, semantic_failures = validate_tree(root)
92
+ all_passed += passed
93
+ all_delimiter += delimiter_failures
94
+ all_parse += parse_failures
95
+ all_semantic += semantic_failures
96
+ total = len(passed) + len(delimiter_failures) + len(parse_failures) + len(semantic_failures)
97
+ print(f"[{root}] SKILL.md files: {total} — parse OK: {len(passed)}")
98
+
99
+ print()
100
+ print(f"Total SKILL.md files: {len(all_passed) + len(all_delimiter) + len(all_parse) + len(all_semantic)}")
101
+ print(f"Parse OK: {len(all_passed)}")
102
+ print(f"Delimiter FAIL (must start with '---'): {len(all_delimiter)}")
103
+ print(f"Parse FAIL: {len(all_parse)}")
104
+ print(f"Semantic issues (model in desc): {len(all_semantic)}")
61
105
  print()
62
106
 
63
- if parse_failures:
107
+ if all_delimiter:
108
+ print("=== DELIMITER FAILURES (file does not start with '---') ===")
109
+ for name, err in all_delimiter:
110
+ print(f" {name}: {err}")
111
+ print()
112
+
113
+ if all_parse:
64
114
  print("=== PARSE FAILURES ===")
65
- for name, err in parse_failures:
115
+ for name, err in all_parse:
66
116
  print(f" {name}: {err}")
67
117
  print()
68
118
 
69
- if semantic_failures:
119
+ if all_semantic:
70
120
  print("=== SEMANTIC ISSUES (model embedded in description) ===")
71
- for name in sorted(semantic_failures):
121
+ for name in sorted(all_semantic):
72
122
  print(f" {name}")
73
123
  print()
74
124
 
75
- if parse_failures or semantic_failures:
76
- print(f"FAIL: {len(parse_failures)} parse + {len(semantic_failures)} semantic issues")
125
+ if all_delimiter or all_parse or all_semantic:
126
+ n = len(all_delimiter) + len(all_parse) + len(all_semantic)
127
+ print(f"FAIL: {n} issues ({len(all_delimiter)} delimiter + {len(all_parse)} parse + {len(all_semantic)} semantic)")
77
128
  sys.exit(1)
78
129
  else:
79
- print("PASS: all SKILL.md YAML frontmatter valid")
130
+ print("PASS: all SKILL.md YAML frontmatter valid (sources + .pi/skills)")
80
131
  sys.exit(0)
@@ -1,7 +1,7 @@
1
+ ---
1
2
  # story: e51s04
2
3
  # story: e45s18
3
4
  # story: e45s31
4
- ---
5
5
  name: audit-code
6
6
  model: haiku
7
7
  effort: standard
@@ -1,7 +1,7 @@
1
- # story: e45s02
2
- <!-- story: e45s12 -->
3
- <!-- story: e79s02 -->
4
1
  ---
2
+ # story: e45s02
3
+ # story: e45s12
4
+ # story: e79s02
5
5
  name: craft-skill
6
6
  model: sonnet
7
7
  effort: standard
@@ -1,6 +1,6 @@
1
- # story: e45s31
2
- <!-- story: e45s14 -->
3
1
  ---
2
+ # story: e45s31
3
+ # story: e45s14
4
4
  name: deepen-architecture
5
5
  model: sonnet
6
6
  effort: standard
@@ -1,5 +1,5 @@
1
- <!-- story: e45s15 -->
2
1
  ---
2
+ # story: e45s15
3
3
  name: deploy
4
4
  description: "Build → verify artifact → deploy → wait → smoke deployment pipeline. Platform-agnostic (MCP or CLI), with configurable timeout, retry with exponential backoff, and integrated health-check. The deploy half of CI/CD: run after build to push to production."
5
5
  model: sonnet
@@ -1,10 +1,10 @@
1
+ ---
1
2
  # story: e80s01
2
3
  # story: e80s03
3
4
  # story: e51s04
4
5
  # story: e45s06
5
6
  # story: e45s08
6
7
  # story: e45s34
7
- ---
8
8
  name: develop-tdd
9
9
  model: sonnet
10
10
  effort: standard
@@ -1,5 +1,5 @@
1
- # story: e45s38
2
1
  ---
2
+ # story: e45s38
3
3
  name: diagnose-stall
4
4
  model: haiku
5
5
  effort: light
@@ -1,5 +1,5 @@
1
- # story: e80s01
2
1
  ---
2
+ # story: e80s01
3
3
  name: enforce-first
4
4
  model: haiku
5
5
  effort: standard
@@ -1,5 +1,5 @@
1
- # story: e51s04
2
1
  ---
2
+ # story: e51s04
3
3
  name: fix-bug
4
4
  model: sonnet
5
5
  effort: standard
@@ -1,6 +1,6 @@
1
+ ---
1
2
  # story: e80s01
2
3
  # story: e45s05
3
- ---
4
4
  name: gate-trace
5
5
  description: "Deterministic traceability quality gate — reads coverage matrix + blind-spot data, applies decision rules with oracle confidence downgrade, emits PASS/CONCERNS/FAIL/WAIVED verdict. Use before release-branch to gate merges on traceability."
6
6
  # story: e38s06