prizmkit 1.1.8 → 1.1.9

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.
Files changed (123) hide show
  1. package/bundled/VERSION.json +3 -3
  2. package/bundled/adapters/codebuddy/skill-adapter.js +21 -7
  3. package/bundled/agents/prizm-dev-team-reviewer.md +53 -173
  4. package/bundled/dev-pipeline/.env.example +45 -0
  5. package/bundled/dev-pipeline/SCHEMA_ANALYSIS.md +535 -0
  6. package/bundled/dev-pipeline/assets/feature-list-example.json +0 -1
  7. package/bundled/dev-pipeline/launch-bugfix-daemon.sh +57 -12
  8. package/bundled/dev-pipeline/launch-feature-daemon.sh +3 -1
  9. package/bundled/dev-pipeline/launch-refactor-daemon.sh +57 -12
  10. package/bundled/dev-pipeline/lib/branch.sh +6 -1
  11. package/bundled/dev-pipeline/lib/common.sh +71 -0
  12. package/bundled/dev-pipeline/lib/heartbeat.sh +2 -2
  13. package/bundled/dev-pipeline/retry-bugfix.sh +60 -23
  14. package/bundled/dev-pipeline/retry-feature.sh +47 -12
  15. package/bundled/dev-pipeline/retry-refactor.sh +105 -23
  16. package/bundled/dev-pipeline/run-bugfix.sh +265 -44
  17. package/bundled/dev-pipeline/run-feature.sh +35 -1
  18. package/bundled/dev-pipeline/run-refactor.sh +376 -51
  19. package/bundled/dev-pipeline/scripts/check-session-status.py +24 -1
  20. package/bundled/dev-pipeline/scripts/detect-stuck.py +195 -85
  21. package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +31 -19
  22. package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +19 -3
  23. package/bundled/dev-pipeline/scripts/generate-refactor-prompt.py +98 -11
  24. package/bundled/dev-pipeline/scripts/init-bugfix-pipeline.py +30 -5
  25. package/bundled/dev-pipeline/scripts/init-pipeline.py +3 -3
  26. package/bundled/dev-pipeline/scripts/init-refactor-pipeline.py +15 -4
  27. package/bundled/dev-pipeline/scripts/parse-stream-progress.py +1 -5
  28. package/bundled/dev-pipeline/scripts/patch-completion-notes.py +191 -0
  29. package/bundled/dev-pipeline/scripts/update-bug-status.py +159 -14
  30. package/bundled/dev-pipeline/scripts/update-feature-status.py +79 -37
  31. package/bundled/dev-pipeline/scripts/update-refactor-status.py +343 -13
  32. package/bundled/dev-pipeline/templates/agent-prompts/dev-fix.md +1 -1
  33. package/bundled/dev-pipeline/templates/agent-prompts/reviewer-review.md +7 -11
  34. package/bundled/dev-pipeline/templates/bootstrap-prompt.md +41 -7
  35. package/bundled/dev-pipeline/templates/bootstrap-tier1.md +27 -3
  36. package/bundled/dev-pipeline/templates/bootstrap-tier2.md +43 -19
  37. package/bundled/dev-pipeline/templates/bootstrap-tier3.md +54 -26
  38. package/bundled/dev-pipeline/templates/bug-fix-list-schema.json +5 -14
  39. package/bundled/dev-pipeline/templates/bugfix-bootstrap-prompt.md +36 -25
  40. package/bundled/dev-pipeline/templates/feature-list-schema.json +23 -11
  41. package/bundled/dev-pipeline/templates/refactor-bootstrap-prompt.md +270 -0
  42. package/bundled/dev-pipeline/templates/refactor-list-schema.json +10 -2
  43. package/bundled/dev-pipeline/templates/sections/context-budget-rules.md +3 -1
  44. package/bundled/dev-pipeline/templates/sections/critical-paths-agent.md +1 -0
  45. package/bundled/dev-pipeline/templates/sections/feature-context.md +2 -0
  46. package/bundled/dev-pipeline/templates/sections/phase-commit-full.md +29 -2
  47. package/bundled/dev-pipeline/templates/sections/phase-commit.md +22 -0
  48. package/bundled/dev-pipeline/templates/sections/phase-deploy-verification.md +2 -2
  49. package/bundled/dev-pipeline/templates/sections/phase-review-agent.md +8 -6
  50. package/bundled/dev-pipeline/templates/sections/phase-review-full.md +7 -5
  51. package/bundled/dev-pipeline/templates/sections/phase-specify-plan-full.md +3 -3
  52. package/bundled/skills/_metadata.json +5 -22
  53. package/bundled/skills/app-planner/SKILL.md +92 -66
  54. package/bundled/skills/app-planner/assets/app-design-guide.md +1 -1
  55. package/bundled/skills/app-planner/references/architecture-decisions.md +1 -1
  56. package/bundled/skills/app-planner/references/project-brief-guide.md +69 -66
  57. package/bundled/skills/bug-fix-workflow/SKILL.md +47 -4
  58. package/bundled/skills/bug-planner/SKILL.md +130 -188
  59. package/bundled/skills/bug-planner/assets/bug-confirmation-template.md +43 -0
  60. package/bundled/skills/bug-planner/references/critic-and-verification.md +44 -0
  61. package/bundled/skills/bug-planner/references/error-recovery.md +73 -0
  62. package/bundled/skills/bug-planner/references/input-formats.md +53 -0
  63. package/bundled/skills/bug-planner/references/schema-validation.md +25 -0
  64. package/bundled/skills/bug-planner/references/severity-rules.md +16 -0
  65. package/bundled/skills/bug-planner/scripts/validate-bug-list.py +1 -5
  66. package/bundled/skills/bugfix-pipeline-launcher/SKILL.md +5 -10
  67. package/bundled/skills/feature-pipeline-launcher/SKILL.md +16 -3
  68. package/bundled/skills/feature-planner/SKILL.md +33 -122
  69. package/bundled/skills/feature-planner/assets/evaluation-guide.md +1 -1
  70. package/bundled/skills/feature-planner/assets/planning-guide.md +21 -5
  71. package/bundled/skills/feature-planner/references/browser-interaction.md +2 -4
  72. package/bundled/skills/feature-planner/references/completeness-review.md +57 -0
  73. package/bundled/skills/feature-planner/references/error-recovery.md +15 -34
  74. package/bundled/skills/feature-planner/references/incremental-feature-planning.md +1 -1
  75. package/bundled/skills/feature-planner/references/new-project-planning.md +2 -2
  76. package/bundled/skills/feature-planner/scripts/validate-and-generate.py +1 -2
  77. package/bundled/skills/feature-workflow/SKILL.md +3 -4
  78. package/bundled/skills/prizm-kit/SKILL.md +39 -49
  79. package/bundled/skills/prizmkit-code-review/SKILL.md +51 -64
  80. package/bundled/skills/prizmkit-code-review/rules/dimensions.md +85 -0
  81. package/bundled/skills/prizmkit-code-review/rules/fix-strategy.md +11 -11
  82. package/bundled/skills/prizmkit-committer/SKILL.md +3 -31
  83. package/bundled/skills/prizmkit-deploy/SKILL.md +34 -31
  84. package/bundled/skills/prizmkit-deploy/assets/deploy-template.md +1 -1
  85. package/bundled/skills/prizmkit-implement/SKILL.md +35 -68
  86. package/bundled/skills/prizmkit-init/SKILL.md +112 -65
  87. package/bundled/skills/prizmkit-init/assets/project-brief-template.md +82 -0
  88. package/bundled/skills/prizmkit-plan/SKILL.md +120 -79
  89. package/bundled/skills/prizmkit-plan/assets/plan-template.md +28 -18
  90. package/bundled/skills/prizmkit-plan/assets/spec-template.md +28 -11
  91. package/bundled/skills/prizmkit-plan/references/clarify-guide.md +3 -3
  92. package/bundled/skills/prizmkit-plan/references/verification-checklist.md +60 -0
  93. package/bundled/skills/prizmkit-prizm-docs/SKILL.md +10 -81
  94. package/bundled/skills/prizmkit-prizm-docs/assets/{PRIZM-SPEC.md → prizm-docs-format.md} +41 -526
  95. package/bundled/skills/prizmkit-prizm-docs/references/op-init.md +46 -0
  96. package/bundled/skills/prizmkit-prizm-docs/references/op-rebuild.md +16 -0
  97. package/bundled/skills/prizmkit-prizm-docs/references/op-status.md +14 -0
  98. package/bundled/skills/prizmkit-prizm-docs/references/op-update.md +19 -0
  99. package/bundled/skills/prizmkit-prizm-docs/references/op-validate.md +17 -0
  100. package/bundled/skills/prizmkit-retrospective/SKILL.md +27 -65
  101. package/bundled/skills/prizmkit-retrospective/references/knowledge-injection-steps.md +3 -4
  102. package/bundled/skills/prizmkit-retrospective/references/structural-sync-steps.md +7 -25
  103. package/bundled/skills/recovery-workflow/SKILL.md +8 -8
  104. package/bundled/skills/refactor-pipeline-launcher/SKILL.md +17 -9
  105. package/bundled/skills/refactor-planner/SKILL.md +23 -41
  106. package/bundled/skills/refactor-workflow/SKILL.md +1 -2
  107. package/bundled/team/prizm-dev-team.json +1 -1
  108. package/bundled/{skills/prizm-kit/assets → templates}/project-memory-template.md +1 -1
  109. package/package.json +1 -1
  110. package/src/clean.js +0 -1
  111. package/src/gitignore-template.js +0 -1
  112. package/src/scaffold.js +10 -3
  113. package/bundled/dev-pipeline/templates/agent-prompts/reviewer-analyze.md +0 -5
  114. package/bundled/dev-pipeline/templates/sections/phase-analyze-agent.md +0 -19
  115. package/bundled/dev-pipeline/templates/sections/phase-analyze-full.md +0 -19
  116. package/bundled/skills/app-planner/references/project-conventions.md +0 -93
  117. package/bundled/skills/prizmkit-analyze/SKILL.md +0 -207
  118. package/bundled/skills/prizmkit-code-review/rules/dimensions-bugfix.md +0 -25
  119. package/bundled/skills/prizmkit-code-review/rules/dimensions-feature.md +0 -43
  120. package/bundled/skills/prizmkit-code-review/rules/dimensions-refactor.md +0 -25
  121. package/bundled/skills/prizmkit-implement/references/deploy-guide-protocol.md +0 -69
  122. package/bundled/skills/prizmkit-verify/SKILL.md +0 -281
  123. package/bundled/skills/prizmkit-verify/scripts/verify-light.py +0 -402
@@ -1,281 +0,0 @@
1
- ---
2
- name: "prizmkit-verify"
3
- description: "Automated framework verification for PrizmKit's 4-layer architecture (Skill → Pipeline → Workflow → Script). Use this skill to validate structural integrity, contract consistency between layers, cross-scenario alignment, and adapter/installer correctness. Trigger whenever: verifying framework health, checking skill contracts, auditing layer integration, running pre-release checks, or after significant framework modifications."
4
- ---
5
-
6
- # PrizmKit Framework Verification
7
-
8
- Verify PrizmKit's four-layer architecture for structural integrity, contract consistency, and cross-scenario alignment.
9
-
10
- ## Execution Modes
11
-
12
- Parse the user's arguments to determine scope and depth:
13
-
14
- | Command | What Runs | When to Use |
15
- |---------|-----------|-------------|
16
- | `/prizmkit-verify light` | Light checks only (R1-R4) | Quick CI gate, seconds |
17
- | `/prizmkit-verify medium` | Light + Medium (R1-R4) | Regular development, recommended default |
18
- | `/prizmkit-verify full` | All rounds (R1-R6) including E2E | Pre-release, after major changes |
19
- | `/prizmkit-verify --round R1` | Specific round only | Targeted check after editing a layer |
20
- | `/prizmkit-verify` (no args) | Same as `medium` | Default |
21
-
22
- ## Architecture Context
23
-
24
- PrizmKit has four layers, bottom to top:
25
-
26
- ```
27
- L1 Skill layer → core/skills/prizmkit-skill/ (10 skills, dev lifecycle)
28
- L2 Pipeline layer → core/skills/orchestration-skill/pipelines/ (7 skills, planners + launchers)
29
- L3 Workflow layer → core/skills/orchestration-skill/workflows/ (4 skills, scenario entry points)
30
- L4 Script layer → dev-pipeline/ (Bash + Python runtime engine)
31
- ```
32
-
33
- Three verification depths, cumulative:
34
- - **Light**: Structural/static checks, scriptable, zero tokens
35
- - **Medium**: AI reads SKILL.md content, verifies inter-layer contracts
36
- - **Deep**: End-to-end scenario traces through all 4 layers
37
-
38
- ## Execution
39
-
40
- ### Phase 0: Setup
41
-
42
- 1. Create output directory: `.prizmkit/verify/` (timestamp-based run dir)
43
- 2. Determine which rounds to run based on user args
44
- 3. Initialize the report structure
45
-
46
- ### Phase 1: Horizontal Verification (R1-R4)
47
-
48
- Run rounds sequentially. For each round, run Light first, then Medium if in scope.
49
-
50
- ---
51
-
52
- #### R1: L1 Skill Layer
53
-
54
- **Target**: All skills in `core/skills/prizmkit-skill/` (expect ~10)
55
-
56
- **Light checks** — run `${SKILL_DIR}/scripts/verify-light.py --round R1` if available, otherwise check manually:
57
-
58
- | Check | How | Pass Criteria |
59
- |-------|-----|---------------|
60
- | Frontmatter validity | Read each SKILL.md YAML header | `name` + `description` present; `name` is lowercase-hyphens; `name` matches directory name |
61
- | Asset reference integrity | Grep `${SKILL_DIR}` in each SKILL.md, resolve path relative to skill dir | Every referenced file exists on disk |
62
- | Cross-skill references | Grep `/prizmkit-*` references in each SKILL.md | Every referenced skill exists under `core/skills/` |
63
- | Orphaned assets | List files in each skill's `assets/`, `scripts/`, `references/` dirs | Every file is referenced by SKILL.md (warn if not) |
64
- | Lint: ESLint | Run `npm run lint` | 0 errors (warnings OK) |
65
- | Lint: Ruff | Run `npm run lint:py` | 0 errors |
66
-
67
- **Medium checks** — read each SKILL.md FULLY and verify artifact chain contracts:
68
-
69
- For each adjacent skill pair in the chain:
70
- `prizmkit-plan → prizmkit-analyze → prizmkit-implement → prizmkit-code-review → prizmkit-retrospective → prizmkit-committer → prizmkit-deploy`
71
-
72
- | Verification Point | What to Check |
73
- |-------------------|---------------|
74
- | Output format defined? | Does the producer skill explicitly describe its output structure (file name, format, key sections)? |
75
- | Input expectation defined? | Does the consumer skill explicitly state what it reads and in what format? |
76
- | Format match | Do output and input specifications agree on structure, field names, file paths? |
77
- | Path convention | Do both skills reference the same directory convention (e.g., `.prizmkit/specs/###-feature-name/`)? |
78
- | Error handling | What happens if upstream artifact is missing or malformed? Is fallback defined? |
79
- | Quality gate | Does each consumer check preconditions before proceeding? |
80
-
81
- Record each pair as: `PASS` / `WARN (gap described)` / `FAIL (mismatch described)`
82
-
83
- ---
84
-
85
- #### R2: L2 Pipeline Layer
86
-
87
- **Target**: All skills in `core/skills/orchestration-skill/pipelines/` (expect 7)
88
-
89
- **Light checks**:
90
-
91
- | Check | How | Pass Criteria |
92
- |-------|-----|---------------|
93
- | Frontmatter validity | Same as R1 | `name` + `description`; name matches dir |
94
- | Asset reference integrity | Same as R1 | All `${SKILL_DIR}` refs resolve |
95
- | Planner→Launcher coupling | For each scenario (feature/bugfix/refactor): check planner mentions correct JSON filename, launcher references correct script | All 3 pairs coupled correctly |
96
- | Script path references | Launchers reference `dev-pipeline/run-*.sh` | All referenced scripts exist and are executable |
97
- | Schema consistency | Compare planner SKILL.md output schema with `dev-pipeline/templates/*-list-schema.json` | Field names, types, required fields match |
98
- | Schema version match | Compare `dev-pipeline/templates/*-list-schema.json` const value with `dev-pipeline/scripts/init-*-pipeline.py` EXPECTED_SCHEMA | Versions identical |
99
-
100
- **Medium checks** — read each SKILL.md FULLY:
101
-
102
- For each scenario (feature, bugfix, refactor):
103
- 1. What JSON format does the planner produce? What fields, what validation?
104
- 2. What JSON format does the launcher expect? What fields does it read?
105
- 3. Do they match? Any fields the launcher expects but planner doesn't produce?
106
- 4. What command does the launcher assemble? What env vars? Do they match `run-*.sh` expectations?
107
-
108
- ---
109
-
110
- #### R3: L3 Workflow Layer
111
-
112
- **Target**: All skills in `core/skills/orchestration-skill/workflows/` (expect 4)
113
-
114
- **Light checks**:
115
-
116
- | Check | How | Pass Criteria |
117
- |-------|-----|---------------|
118
- | Frontmatter validity | Same as R1 | `name` + `description`; name matches dir |
119
- | Pipeline skill references | Grep each workflow for planner/launcher skill names | All referenced pipeline skills exist |
120
- | Checkpoint naming | Grep for `CP-` patterns | Follows `CP-{XW}-{N}` convention |
121
- | Flow completeness markers | Each workflow has: When to Use, Execution phases, Error handling table, Relationship table | All sections present |
122
-
123
- **Medium checks** — read each SKILL.md FULLY:
124
-
125
- | Verification Point | What to Check |
126
- |-------------------|---------------|
127
- | Workflow → Pipeline handoff | What does workflow pass to each pipeline skill? Is the input format documented? |
128
- | Flow completeness | feature-workflow: requirements→planning→launch→monitor? bug-fix-workflow: diagnosis→triage→fix→review→commit? refactor-workflow: goals→planning→launch→monitor? recovery-workflow: detect→diagnose→recover? |
129
- | Fast path integration | If fast path exists, is there a decision tree for when to use it? |
130
- | Cross-workflow consistency | Same checkpoint naming, phase structure, error handling patterns? |
131
-
132
- ---
133
-
134
- #### R4: L4 Script Layer
135
-
136
- **Target**: `dev-pipeline/` directory
137
-
138
- **Light checks**:
139
-
140
- | Check | How | Pass Criteria |
141
- |-------|-----|---------------|
142
- | Shell scripts executable | `ls -la dev-pipeline/*.sh` | All `.sh` files have `+x` permission |
143
- | Python scripts compile | `python3 -m py_compile` each `.py` file | All compile without error |
144
- | Bash lib sourcing | Grep `run-*.sh` for `source.*lib/` | Each sources common.sh, heartbeat.sh, branch.sh |
145
- | JSON templates valid | `python3 -c "import json; json.load(open(f))"` for each `.json` in `templates/` | All parse without error |
146
- | Ruff Python lint | `ruff check dev-pipeline/scripts/` | 0 errors |
147
- | Test file existence | List `dev-pipeline/tests/` | At least test files exist for prompt generation |
148
-
149
- **Medium checks** — read key scripts:
150
-
151
- | Verification Point | What to Check |
152
- |-------------------|---------------|
153
- | Shell → Python integration | For each `run-*.sh`: list all Python scripts invoked, verify each exists, verify argument names match |
154
- | Bootstrap prompt generation | Read `generate-bootstrap-prompt.py` (or per-scenario variant): does it reference correct skill names? Are all `{{PLACEHOLDER}}` variables populated? |
155
- | State management | Read `init-*-pipeline.py`: correct schema validation? Proper state dir initialization? |
156
- | Cross-scenario consistency | Compare `run-feature.sh` vs `run-bugfix.sh` vs `run-refactor.sh`: same structure? Same error handling patterns? Note intentional divergences vs unintentional gaps |
157
-
158
- ---
159
-
160
- ### Phase 2: Vertical E2E Verification (R5-R6)
161
-
162
- Only runs in `full` mode. For each scenario, trace data flow through all 4 layers.
163
-
164
- #### R5: Feature Scenario
165
-
166
- Trace "Add user authentication with JWT" through:
167
-
168
- 1. **L3→L2**: feature-workflow → feature-planner → feature-pipeline-launcher
169
- - What format does workflow pass to planner?
170
- - What JSON does planner produce?
171
- - What command does launcher assemble?
172
-
173
- 2. **L2→L4**: feature-pipeline-launcher → run-feature.sh
174
- - What args/env vars are passed?
175
- - How does init-pipeline.py consume .prizmkit/plans/feature-list.json?
176
- - What bootstrap prompt does generate-bootstrap-prompt.py produce?
177
-
178
- 3. **L4→L1**: run-feature.sh → AI CLI → Skills
179
- - What skills does the bootstrap prompt reference?
180
- - In what order?
181
- - Are skill names correct?
182
-
183
- At each transition, verify: **format match**, **field completeness**, **path consistency**, **error propagation**.
184
-
185
- #### R6: Bugfix + Refactor Scenarios
186
-
187
- Same trace for:
188
- - Bugfix: "Fix login crash when email is empty"
189
- - Refactor: "Extract authentication logic into shared module"
190
-
191
- Then cross-scenario comparison:
192
- - Layer transition patterns structurally similar?
193
- - Schema conventions consistent (F-NNN / B-NNN / R-NNN)?
194
- - Bootstrap prompt patterns consistent?
195
- - State management patterns consistent?
196
- - Intentional divergences documented?
197
-
198
- ---
199
-
200
- ### Phase 3: Supplementary Checks
201
-
202
- These address gaps identified in the first verification run. Include in `medium` and `full` modes.
203
-
204
- #### S1: Adapter Layer Verification
205
-
206
- | Check | How |
207
- |-------|-----|
208
- | Claude adapter output | Run `node adapters/claude/command-adapter.js` on a sample skill, verify output format |
209
- | CodeBuddy adapter output | Run `node adapters/codebuddy/skill-adapter.js` on same skill, verify output |
210
- | Cross-platform equivalence | Diff the two outputs for semantic equivalence |
211
- | ${SKILL_DIR} resolution | Verify Claude resolves to `.claude/command-assets/`, CodeBuddy to `.codebuddy/skills/` |
212
-
213
- #### S2: Installer & Distribution Verification
214
-
215
- | Check | How |
216
- |-------|-----|
217
- | _metadata.json completeness | All skills listed in `core/skills/_metadata.json` suites? |
218
- | Bundle sync | `npm run bundle && npm run bundle:verify` passes |
219
- | Skill count | Bundled skill count matches source skill count |
220
-
221
- #### S3: Rules Consistency
222
-
223
- | Check | How |
224
- |-------|-----|
225
- | Rules exist | All files in `core/rules/` referenced by `_rules-metadata.json` |
226
- | Rule-skill alignment | Rules reference skill names that exist |
227
-
228
- ---
229
-
230
- ## Report Format
231
-
232
- Generate the verification report at `.prizmkit/verify/verify-report-{timestamp}.md`:
233
-
234
- ```markdown
235
- # PrizmKit Verification Report
236
- **Date**: {date} **Mode**: {light|medium|full}
237
-
238
- ## Summary
239
- | Round | Layer | Light | Medium | Deep | Issues |
240
- |-------|-------|-------|--------|------|--------|
241
- | R1 | L1 Skill | PASS/WARN/FAIL | PASS/WARN/FAIL | — | count |
242
- | R2 | L2 Pipeline | ... | ... | — | count |
243
- | R3 | L3 Workflow | ... | ... | — | count |
244
- | R4 | L4 Script | ... | ... | — | count |
245
- | R5 | E2E Feature | — | — | PASS/WARN/FAIL | count |
246
- | R6 | E2E Bug+Refactor | — | — | PASS/WARN/FAIL | count |
247
- | S1 | Adapters | ... | ... | — | count |
248
- | S2 | Distribution | ... | ... | — | count |
249
- | S3 | Rules | ... | ... | — | count |
250
-
251
- ## Issues by Severity
252
- ### Critical
253
- - [C1] Description... (Round, Layer, Location)
254
-
255
- ### High
256
- - [H1] Description...
257
-
258
- ### Medium
259
- - [M1] Description...
260
-
261
- ## Cross-Scenario Comparison (full mode only)
262
- | Dimension | Feature | Bugfix | Refactor | Consistent? |
263
- |-----------|---------|--------|----------|-------------|
264
- | ... | ... | ... | ... | ✅/⚠️ |
265
-
266
- ## Recommendations
267
- 1. **P0**: ...
268
- 2. **P1**: ...
269
- ```
270
-
271
- ## Parallelization Strategy
272
-
273
- For efficiency, run independent checks concurrently:
274
- - R1 Light + R2 Light + R3 Light + R4 Light can run in parallel
275
- - R1 Medium depends on R1 Light passing
276
- - R5/R6 depend on R1-R4 completing (need full picture of each layer)
277
- - S1/S2/S3 can run in parallel with R1-R4
278
-
279
- ## Previous Verification Findings
280
-
281
- Reference `docs/framework-verification-report.md` for the baseline findings from the initial verification run. This helps track whether previously identified issues have been resolved.
@@ -1,402 +0,0 @@
1
- #!/usr/bin/env python3
2
- """PrizmKit Light Verification Script — static checks for framework integrity.
3
-
4
- Usage:
5
- python3 verify-light.py # Run all rounds
6
- python3 verify-light.py --round R1 # Run specific round
7
- python3 verify-light.py --round R1 R2 R4 # Run multiple rounds
8
- """
9
-
10
- import argparse
11
- import json
12
- import os
13
- import re
14
- import subprocess
15
- import sys
16
- from pathlib import Path
17
-
18
- # --- Configuration ---
19
-
20
- PROJECT_ROOT = Path(__file__).resolve().parents[5] # core/skills/prizmkit-skill/prizmkit-verify/scripts/verify-light.py → root (5 levels up)
21
-
22
- SKILL_LAYER_DIR = PROJECT_ROOT / "core" / "skills" / "prizmkit-skill"
23
- PIPELINE_LAYER_DIR = PROJECT_ROOT / "core" / "skills" / "orchestration-skill" / "pipelines"
24
- WORKFLOW_LAYER_DIR = PROJECT_ROOT / "core" / "skills" / "orchestration-skill" / "workflows"
25
- DEV_PIPELINE_DIR = PROJECT_ROOT / "dev-pipeline"
26
- ALL_SKILLS_DIR = PROJECT_ROOT / "core" / "skills"
27
-
28
- # Expected items per layer
29
- EXPECTED_PIPELINE_SKILLS = {
30
- "app-planner", "feature-planner", "bug-planner", "refactor-planner",
31
- "feature-pipeline-launcher", "bugfix-pipeline-launcher", "refactor-pipeline-launcher",
32
- }
33
- EXPECTED_WORKFLOW_SKILLS = {
34
- "feature-workflow", "bug-fix-workflow", "refactor-workflow", "recovery-workflow",
35
- }
36
-
37
- # --- Helpers ---
38
-
39
- class Result:
40
- def __init__(self):
41
- self.passed = 0
42
- self.warned = 0
43
- self.failed = 0
44
- self.details = []
45
-
46
- def ok(self, msg):
47
- self.passed += 1
48
- self.details.append(("PASS", msg))
49
-
50
- def warn(self, msg):
51
- self.warned += 1
52
- self.details.append(("WARN", msg))
53
-
54
- def fail(self, msg):
55
- self.failed += 1
56
- self.details.append(("FAIL", msg))
57
-
58
- @property
59
- def status(self):
60
- if self.failed > 0:
61
- return "FAIL"
62
- if self.warned > 0:
63
- return "WARN"
64
- return "PASS"
65
-
66
- def summary(self):
67
- return f"PASS={self.passed} WARN={self.warned} FAIL={self.failed}"
68
-
69
-
70
- def parse_frontmatter(skill_md_path):
71
- """Extract YAML frontmatter from SKILL.md."""
72
- text = skill_md_path.read_text(encoding="utf-8")
73
- match = re.match(r"^---\n(.*?)\n---", text, re.DOTALL)
74
- if not match:
75
- return {}
76
- fm = {}
77
- for line in match.group(1).split("\n"):
78
- if ":" in line:
79
- key, val = line.split(":", 1)
80
- fm[key.strip()] = val.strip().strip('"').strip("'")
81
- return fm
82
-
83
-
84
- def find_skill_dirs(base_dir):
85
- """Find all directories containing SKILL.md under base_dir."""
86
- return sorted(
87
- d for d in base_dir.iterdir()
88
- if d.is_dir() and (d / "SKILL.md").exists()
89
- )
90
-
91
-
92
- def collect_all_skill_names():
93
- """Collect all known skill names across all categories."""
94
- names = set()
95
- for category_dir in ALL_SKILLS_DIR.iterdir():
96
- if not category_dir.is_dir() or category_dir.name.startswith("."):
97
- continue
98
- # Direct skill dirs
99
- for d in category_dir.iterdir():
100
- if d.is_dir() and (d / "SKILL.md").exists():
101
- names.add(d.name)
102
- # Nested (pipelines/, workflows/)
103
- if d.is_dir() and not (d / "SKILL.md").exists():
104
- for sub in d.iterdir():
105
- if sub.is_dir() and (sub / "SKILL.md").exists():
106
- names.add(sub.name)
107
- return names
108
-
109
-
110
- # --- Round Checks ---
111
-
112
- def run_r1(result: Result):
113
- """R1: L1 Skill Layer Light checks."""
114
- print("\n=== R1: L1 Skill Layer ===")
115
- skill_dirs = find_skill_dirs(SKILL_LAYER_DIR)
116
- all_skill_names = collect_all_skill_names()
117
-
118
- if not skill_dirs:
119
- result.fail("No skill directories found in prizmkit-skill/")
120
- return
121
-
122
- print(f" Found {len(skill_dirs)} skills")
123
-
124
- for skill_dir in skill_dirs:
125
- skill_name = skill_dir.name
126
- skill_md = skill_dir / "SKILL.md"
127
-
128
- # 1. Frontmatter validation
129
- fm = parse_frontmatter(skill_md)
130
- if not fm.get("name"):
131
- result.fail(f"[{skill_name}] Missing 'name' in frontmatter")
132
- elif fm["name"] != skill_name:
133
- result.fail(f"[{skill_name}] name '{fm['name']}' != dir '{skill_name}'")
134
- else:
135
- result.ok(f"[{skill_name}] Frontmatter name OK")
136
-
137
- if not fm.get("description"):
138
- result.fail(f"[{skill_name}] Missing 'description' in frontmatter")
139
- else:
140
- result.ok(f"[{skill_name}] Frontmatter description OK")
141
-
142
- # 2. ${SKILL_DIR} reference resolution
143
- content = skill_md.read_text(encoding="utf-8")
144
- refs = re.findall(r'\$\{SKILL_DIR\}/([^\s`"\')]+)', content)
145
- for ref in refs:
146
- resolved = skill_dir / ref
147
- if resolved.exists():
148
- result.ok(f"[{skill_name}] Asset ref '{ref}' exists")
149
- else:
150
- result.fail(f"[{skill_name}] Asset ref '{ref}' NOT FOUND at {resolved}")
151
-
152
- # 3. Cross-skill references
153
- cross_refs = re.findall(r'(?<!\w)/prizmkit-[\w-]+(?=[\s`"\',\)])', content)
154
- for ref in cross_refs:
155
- ref_name = ref.lstrip("/")
156
- if ref_name in all_skill_names:
157
- result.ok(f"[{skill_name}] Cross-ref '{ref_name}' exists")
158
- else:
159
- result.warn(f"[{skill_name}] Cross-ref '{ref_name}' not found as skill dir")
160
-
161
- # 4. ESLint
162
- try:
163
- lint_result = subprocess.run(
164
- ["npm", "run", "lint"], capture_output=True, text=True,
165
- cwd=str(PROJECT_ROOT), timeout=30,
166
- )
167
- errors = len(re.findall(r"(\d+) error[^s]", lint_result.stdout + lint_result.stderr))
168
- if lint_result.returncode == 0 or errors == 0:
169
- result.ok("ESLint: 0 errors")
170
- else:
171
- result.fail(f"ESLint: {errors} errors found")
172
- except (subprocess.TimeoutExpired, FileNotFoundError) as e:
173
- result.warn(f"ESLint: could not run ({e})")
174
-
175
- # 5. Ruff
176
- try:
177
- ruff_result = subprocess.run(
178
- ["npm", "run", "lint:py"], capture_output=True, text=True,
179
- cwd=str(PROJECT_ROOT), timeout=30,
180
- )
181
- if ruff_result.returncode == 0:
182
- result.ok("Ruff: all checks passed")
183
- else:
184
- result.fail(f"Ruff: {ruff_result.stdout.strip()}")
185
- except (subprocess.TimeoutExpired, FileNotFoundError) as e:
186
- result.warn(f"Ruff: could not run ({e})")
187
-
188
-
189
- def run_r2(result: Result):
190
- """R2: L2 Pipeline Layer Light checks."""
191
- print("\n=== R2: L2 Pipeline Layer ===")
192
- skill_dirs = find_skill_dirs(PIPELINE_LAYER_DIR)
193
- found_names = {d.name for d in skill_dirs}
194
-
195
- # Check expected skills present
196
- for expected in EXPECTED_PIPELINE_SKILLS:
197
- if expected in found_names:
198
- result.ok(f"[{expected}] Skill exists")
199
- else:
200
- result.fail(f"[{expected}] Expected skill NOT FOUND")
201
-
202
- # Frontmatter validation
203
- for skill_dir in skill_dirs:
204
- fm = parse_frontmatter(skill_dir / "SKILL.md")
205
- if fm.get("name") == skill_dir.name and fm.get("description"):
206
- result.ok(f"[{skill_dir.name}] Frontmatter OK")
207
- else:
208
- result.fail(f"[{skill_dir.name}] Frontmatter invalid: {fm}")
209
-
210
- # Schema version consistency
211
- scenarios = [
212
- ("feature", "feature-list-schema.json", "init-pipeline.py"),
213
- ("bugfix", "bug-fix-list-schema.json", "init-bugfix-pipeline.py"),
214
- ("refactor", "refactor-list-schema.json", "init-refactor-pipeline.py"),
215
- ]
216
- for scenario, schema_file, init_script in scenarios:
217
- schema_path = DEV_PIPELINE_DIR / "templates" / schema_file
218
- init_path = DEV_PIPELINE_DIR / "scripts" / init_script
219
-
220
- if not schema_path.exists():
221
- result.fail(f"[{scenario}] Schema file missing: {schema_file}")
222
- continue
223
- if not init_path.exists():
224
- result.fail(f"[{scenario}] Init script missing: {init_script}")
225
- continue
226
-
227
- # Extract schema const value
228
- try:
229
- schema_data = json.loads(schema_path.read_text())
230
- schema_const = (
231
- schema_data.get("properties", {})
232
- .get("$schema", {})
233
- .get("const", "NOT_FOUND")
234
- )
235
- except json.JSONDecodeError:
236
- result.fail(f"[{scenario}] Schema file is not valid JSON")
237
- continue
238
-
239
- # Extract expected schema from init script
240
- init_content = init_path.read_text()
241
- match = re.search(r'EXPECTED_SCHEMA\s*=\s*["\']([^"\']+)', init_content)
242
- init_expected = match.group(1) if match else "NOT_FOUND"
243
-
244
- if schema_const == init_expected:
245
- result.ok(f"[{scenario}] Schema version match: {schema_const}")
246
- else:
247
- result.fail(f"[{scenario}] Schema version MISMATCH: template={schema_const}, init={init_expected}")
248
-
249
- # Launcher script path references
250
- for scenario, script in [("feature", "run-feature.sh"), ("bugfix", "run-bugfix.sh"), ("refactor", "run-refactor.sh")]:
251
- script_path = DEV_PIPELINE_DIR / script
252
- if script_path.exists() and os.access(script_path, os.X_OK):
253
- result.ok(f"[{scenario}] Script {script} exists and executable")
254
- elif script_path.exists():
255
- result.warn(f"[{scenario}] Script {script} exists but NOT executable")
256
- else:
257
- result.fail(f"[{scenario}] Script {script} NOT FOUND")
258
-
259
-
260
- def run_r3(result: Result):
261
- """R3: L3 Workflow Layer Light checks."""
262
- print("\n=== R3: L3 Workflow Layer ===")
263
- skill_dirs = find_skill_dirs(WORKFLOW_LAYER_DIR)
264
- found_names = {d.name for d in skill_dirs}
265
- pipeline_names = {d.name for d in find_skill_dirs(PIPELINE_LAYER_DIR)}
266
-
267
- # Check expected skills
268
- for expected in EXPECTED_WORKFLOW_SKILLS:
269
- if expected in found_names:
270
- result.ok(f"[{expected}] Workflow exists")
271
- else:
272
- result.fail(f"[{expected}] Expected workflow NOT FOUND")
273
-
274
- for skill_dir in skill_dirs:
275
- skill_name = skill_dir.name
276
- skill_md = skill_dir / "SKILL.md"
277
-
278
- # Frontmatter
279
- fm = parse_frontmatter(skill_md)
280
- if fm.get("name") == skill_name and fm.get("description"):
281
- result.ok(f"[{skill_name}] Frontmatter OK")
282
- else:
283
- result.fail(f"[{skill_name}] Frontmatter invalid")
284
-
285
- # Pipeline skill references
286
- content = skill_md.read_text(encoding="utf-8")
287
- for pipeline_ref in re.findall(r'`([\w-]+-planner|[\w-]+-pipeline-launcher)`', content):
288
- if pipeline_ref in pipeline_names:
289
- result.ok(f"[{skill_name}] Pipeline ref '{pipeline_ref}' exists")
290
- else:
291
- result.warn(f"[{skill_name}] Pipeline ref '{pipeline_ref}' not found")
292
-
293
- # Checkpoint naming
294
- checkpoints = re.findall(r'CP-\w+-\d+', content)
295
- if checkpoints:
296
- result.ok(f"[{skill_name}] {len(checkpoints)} checkpoints found (CP-*-N pattern)")
297
- else:
298
- result.warn(f"[{skill_name}] No checkpoint markers found")
299
-
300
-
301
- def run_r4(result: Result):
302
- """R4: L4 Script Layer Light checks."""
303
- print("\n=== R4: L4 Script Layer ===")
304
-
305
- # 1. Shell scripts executable
306
- for sh_file in sorted(DEV_PIPELINE_DIR.glob("*.sh")):
307
- if os.access(sh_file, os.X_OK):
308
- result.ok(f"[{sh_file.name}] Executable")
309
- else:
310
- result.fail(f"[{sh_file.name}] NOT executable")
311
-
312
- # 2. Python scripts compile
313
- scripts_dir = DEV_PIPELINE_DIR / "scripts"
314
- if scripts_dir.exists():
315
- for py_file in sorted(scripts_dir.glob("*.py")):
316
- try:
317
- subprocess.run(
318
- [sys.executable, "-m", "py_compile", str(py_file)],
319
- capture_output=True, text=True, timeout=10,
320
- )
321
- result.ok(f"[{py_file.name}] Compiles OK")
322
- except subprocess.TimeoutExpired:
323
- result.warn(f"[{py_file.name}] Compile check timed out")
324
-
325
- # 3. Bash lib sourcing
326
- for run_script in ["run-feature.sh", "run-bugfix.sh", "run-refactor.sh"]:
327
- script_path = DEV_PIPELINE_DIR / run_script
328
- if not script_path.exists():
329
- result.fail(f"[{run_script}] NOT FOUND")
330
- continue
331
- content = script_path.read_text(encoding="utf-8")
332
- for lib in ["common.sh", "heartbeat.sh", "branch.sh"]:
333
- if lib in content:
334
- result.ok(f"[{run_script}] Sources {lib}")
335
- else:
336
- result.fail(f"[{run_script}] Does NOT source {lib}")
337
-
338
- # 4. JSON templates valid
339
- templates_dir = DEV_PIPELINE_DIR / "templates"
340
- if templates_dir.exists():
341
- for json_file in sorted(templates_dir.glob("*.json")):
342
- try:
343
- json.loads(json_file.read_text())
344
- result.ok(f"[{json_file.name}] Valid JSON")
345
- except json.JSONDecodeError as e:
346
- result.fail(f"[{json_file.name}] Invalid JSON: {e}")
347
-
348
- # 5. Test file existence
349
- tests_dir = DEV_PIPELINE_DIR / "tests"
350
- if tests_dir.exists():
351
- test_files = list(tests_dir.glob("test_*.py"))
352
- if test_files:
353
- result.ok(f"Test files found: {len(test_files)}")
354
- else:
355
- result.warn("No test_*.py files found in dev-pipeline/tests/")
356
- else:
357
- result.warn("dev-pipeline/tests/ directory not found")
358
-
359
-
360
- # --- Main ---
361
-
362
- def main():
363
- parser = argparse.ArgumentParser(description="PrizmKit Light Verification")
364
- parser.add_argument("--round", nargs="*", default=["R1", "R2", "R3", "R4"],
365
- help="Rounds to run (R1, R2, R3, R4)")
366
- args = parser.parse_args()
367
-
368
- rounds_to_run = [r.upper() for r in args.round]
369
- result = Result()
370
-
371
- round_map = {"R1": run_r1, "R2": run_r2, "R3": run_r3, "R4": run_r4}
372
-
373
- for round_name in rounds_to_run:
374
- if round_name in round_map:
375
- round_map[round_name](result)
376
- else:
377
- print(f" Unknown round: {round_name}")
378
-
379
- # Print results
380
- print("\n" + "=" * 60)
381
- print(f" RESULT: {result.status}")
382
- print(f" {result.summary()}")
383
- print("=" * 60)
384
-
385
- if result.failed > 0:
386
- print("\n FAILURES:")
387
- for status, msg in result.details:
388
- if status == "FAIL":
389
- print(f" {msg}")
390
-
391
- if result.warned > 0:
392
- print("\n WARNINGS:")
393
- for status, msg in result.details:
394
- if status == "WARN":
395
- print(f" {msg}")
396
-
397
- print()
398
- return 0 if result.failed == 0 else 1
399
-
400
-
401
- if __name__ == "__main__":
402
- sys.exit(main())