bmad-module-skill-forge 1.4.1 → 1.5.1

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 (231) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/README.md +0 -8
  3. package/docs/_data/pinned.yaml +1 -1
  4. package/docs/_internal/STABILITY.md +1 -1
  5. package/docs/architecture.md +2 -2
  6. package/docs/examples.md +1 -1
  7. package/docs/workflows.md +5 -5
  8. package/package.json +2 -2
  9. package/src/README.md +1 -1
  10. package/src/knowledge/ccc-bridge.md +12 -12
  11. package/src/knowledge/qmd-registry.md +5 -5
  12. package/src/shared/health-check.md +5 -5
  13. package/src/shared/references/description-guard-protocol.md +100 -0
  14. package/src/shared/references/output-contract-schema.md +1 -1
  15. package/src/shared/scripts/schemas/skf-brief-result-envelope.v1.json +6 -6
  16. package/src/shared/scripts/schemas/skf-setup-result-envelope.v1.json +9 -3
  17. package/src/shared/scripts/schemas/skf-update-result-envelope.v1.json +149 -0
  18. package/src/shared/scripts/schemas/skill-brief.v1.json +22 -2
  19. package/src/shared/scripts/skf-build-change-manifest.py +420 -0
  20. package/src/shared/scripts/skf-check-workspace-drift.py +321 -0
  21. package/src/shared/scripts/skf-compare-file-hashes.py +357 -0
  22. package/src/shared/scripts/skf-description-guard.py +359 -0
  23. package/src/shared/scripts/skf-detect-language.py +2 -2
  24. package/src/shared/scripts/skf-detect-scripts-assets.py +613 -0
  25. package/src/shared/scripts/skf-detect-tools.py +147 -16
  26. package/src/shared/scripts/skf-detect-workspaces.py +1 -1
  27. package/src/shared/scripts/skf-disqualify-candidates.py +576 -0
  28. package/src/shared/scripts/skf-emit-brief-result-envelope.py +3 -3
  29. package/src/shared/scripts/skf-emit-result-envelope.py +93 -9
  30. package/src/shared/scripts/skf-enumerate-stack-skills.py +514 -0
  31. package/src/shared/scripts/skf-forge-tier-rw.py +11 -11
  32. package/src/shared/scripts/skf-hash-content.py +284 -0
  33. package/src/shared/scripts/skf-load-provenance.py +295 -0
  34. package/src/shared/scripts/skf-manifest-ops.py +22 -6
  35. package/src/shared/scripts/skf-merge-ccc-exclusions.py +34 -4
  36. package/src/shared/scripts/skf-pair-intersect.py +250 -0
  37. package/src/shared/scripts/skf-provenance-gap-dispatch.py +433 -0
  38. package/src/shared/scripts/skf-qmd-classify-collections.py +42 -8
  39. package/src/shared/scripts/skf-recommend-scope-type.py +2 -2
  40. package/src/shared/scripts/skf-render-quick-metadata.py +2 -2
  41. package/src/shared/scripts/skf-resolve-authoritative-files.py +504 -0
  42. package/src/shared/scripts/skf-scan-manifests.py +738 -0
  43. package/src/shared/scripts/skf-scan-skill-md-structure.py +375 -0
  44. package/src/shared/scripts/skf-update-active-symlink.py +315 -0
  45. package/src/shared/scripts/skf-validate-brief-inputs.py +5 -5
  46. package/src/shared/scripts/skf-validate-brief-schema.py +348 -0
  47. package/src/shared/scripts/skf-write-skill-brief.py +61 -5
  48. package/src/skf-analyze-source/SKILL.md +69 -16
  49. package/src/skf-analyze-source/assets/skill-brief-schema.md +1 -1
  50. package/src/skf-analyze-source/customize.toml +55 -0
  51. package/src/skf-analyze-source/{steps-c/step-01b-continue.md → references/continue.md} +12 -12
  52. package/src/skf-analyze-source/{steps-c/step-06-generate-briefs.md → references/generate-briefs.md} +29 -10
  53. package/src/skf-analyze-source/{steps-c/step-07-health-check.md → references/health-check.md} +5 -3
  54. package/src/skf-analyze-source/{steps-c/step-03-identify-units.md → references/identify-units.md} +48 -14
  55. package/src/skf-analyze-source/{steps-c/step-01-init.md → references/init.md} +32 -9
  56. package/src/skf-analyze-source/{steps-c/step-04-map-and-detect.md → references/map-and-detect.md} +52 -25
  57. package/src/skf-analyze-source/{steps-c/step-05-recommend.md → references/recommend.md} +15 -8
  58. package/src/skf-analyze-source/{steps-c/step-02-scan-project.md → references/scan-project.md} +16 -10
  59. package/src/skf-analyze-source/references/unit-detection-heuristics.md +2 -0
  60. package/src/skf-analyze-source/templates/analysis-report-template.md +6 -6
  61. package/src/skf-audit-skill/SKILL.md +66 -15
  62. package/src/skf-audit-skill/assets/drift-report-template.md +6 -5
  63. package/src/skf-audit-skill/customize.toml +49 -0
  64. package/src/skf-audit-skill/{steps-c/step-07-health-check.md → references/health-check.md} +5 -3
  65. package/src/skf-audit-skill/{steps-c/step-01-init.md → references/init.md} +63 -19
  66. package/src/skf-audit-skill/{steps-c/step-02-re-index.md → references/re-index.md} +11 -11
  67. package/src/skf-audit-skill/{steps-c/step-06-report.md → references/report.md} +25 -7
  68. package/src/skf-audit-skill/{steps-c/step-04-semantic-diff.md → references/semantic-diff.md} +6 -6
  69. package/src/skf-audit-skill/{steps-c/step-05-severity-classify.md → references/severity-classify.md} +5 -5
  70. package/src/skf-audit-skill/references/severity-rules.md +2 -0
  71. package/src/skf-audit-skill/{steps-c/step-03-structural-diff.md → references/structural-diff.md} +35 -17
  72. package/src/skf-brief-skill/SKILL.md +49 -19
  73. package/src/skf-brief-skill/assets/description-voice-examples.md +1 -1
  74. package/src/skf-brief-skill/assets/skill-brief-schema.md +32 -2
  75. package/src/skf-brief-skill/customize.toml +44 -0
  76. package/src/skf-brief-skill/{steps-c/step-02-analyze-target.md → references/analyze-target.md} +27 -15
  77. package/src/skf-brief-skill/{steps-c/step-04-confirm-brief.md → references/confirm-brief.md} +13 -10
  78. package/src/skf-brief-skill/references/draft-checkpoint.md +4 -4
  79. package/src/skf-brief-skill/{steps-c/step-01-gather-intent.md → references/gather-intent.md} +35 -29
  80. package/src/skf-brief-skill/references/headless-args.md +9 -9
  81. package/src/skf-brief-skill/references/headless-source-authority-detection.md +1 -1
  82. package/src/skf-brief-skill/{steps-c/step-06-health-check.md → references/health-check.md} +4 -2
  83. package/src/skf-brief-skill/references/portfolio-similarity-check.md +2 -2
  84. package/src/skf-brief-skill/references/qmd-collection-registration.md +2 -2
  85. package/src/skf-brief-skill/{steps-c/step-03-scope-definition.md → references/scope-definition.md} +27 -20
  86. package/src/skf-brief-skill/references/version-resolution.md +2 -2
  87. package/src/skf-brief-skill/{steps-c/step-05-write-brief.md → references/write-brief.md} +29 -16
  88. package/src/skf-create-skill/SKILL.md +25 -19
  89. package/src/skf-create-skill/assets/compile-assembly-rules.md +3 -3
  90. package/src/skf-create-skill/assets/skill-sections.md +5 -5
  91. package/src/skf-create-skill/assets/tessl-dismissal-rules.md +11 -11
  92. package/src/skf-create-skill/customize.toml +35 -0
  93. package/src/skf-create-skill/references/authoritative-files-protocol.md +142 -0
  94. package/src/skf-create-skill/{steps-c/step-05-compile.md → references/compile.md} +16 -16
  95. package/src/skf-create-skill/{steps-c/step-03d-component-extraction.md → references/component-extraction.md} +16 -16
  96. package/src/skf-create-skill/{steps-c/step-02-ecosystem-check.md → references/ecosystem-check.md} +4 -4
  97. package/src/skf-create-skill/{steps-c/step-04-enrich.md → references/enrich.md} +3 -3
  98. package/src/skf-create-skill/{steps-c/step-03-extract.md → references/extract.md} +52 -120
  99. package/src/skf-create-skill/references/extraction-patterns.md +10 -8
  100. package/src/skf-create-skill/{steps-c/step-07-generate-artifacts.md → references/generate-artifacts.md} +11 -11
  101. package/src/skf-create-skill/{steps-c/step-09-health-check.md → references/health-check.md} +4 -2
  102. package/src/skf-create-skill/{steps-c/step-01-load-brief.md → references/load-brief.md} +40 -32
  103. package/src/skf-create-skill/{steps-c/step-08-report.md → references/report.md} +8 -8
  104. package/src/skf-create-skill/references/source-resolution-protocols.md +6 -6
  105. package/src/skf-create-skill/{steps-c/sub/step-02b-ccc-discover.md → references/sub/ccc-discover.md} +5 -5
  106. package/src/skf-create-skill/{steps-c/sub/step-03c-fetch-docs.md → references/sub/fetch-docs.md} +28 -12
  107. package/src/skf-create-skill/{steps-c/sub/step-03b-fetch-temporal.md → references/sub/fetch-temporal.md} +81 -50
  108. package/src/skf-create-skill/{steps-c/step-06-validate.md → references/validate.md} +48 -28
  109. package/src/skf-create-stack-skill/SKILL.md +76 -17
  110. package/src/skf-create-stack-skill/assets/provenance-map-schema.md +102 -0
  111. package/src/skf-create-stack-skill/assets/stack-skill-template.md +1 -1
  112. package/src/skf-create-stack-skill/customize.toml +46 -0
  113. package/src/skf-create-stack-skill/{steps-c/step-06-compile-stack.md → references/compile-stack.md} +6 -5
  114. package/src/skf-create-stack-skill/references/compose-mode-rules.md +3 -1
  115. package/src/skf-create-stack-skill/{steps-c/step-05-detect-integrations.md → references/detect-integrations.md} +37 -11
  116. package/src/skf-create-stack-skill/{steps-c/step-02-detect-manifests.md → references/detect-manifests.md} +32 -28
  117. package/src/skf-create-stack-skill/{steps-c/step-07-generate-output.md → references/generate-output.md} +11 -85
  118. package/src/skf-create-stack-skill/{steps-c/step-10-health-check.md → references/health-check.md} +4 -2
  119. package/src/skf-create-stack-skill/{steps-c/step-01-init.md → references/init.md} +70 -4
  120. package/src/skf-create-stack-skill/references/integration-patterns.md +2 -0
  121. package/src/skf-create-stack-skill/references/manifest-patterns.md +2 -0
  122. package/src/skf-create-stack-skill/{steps-c/step-04-parallel-extract.md → references/parallel-extract.md} +44 -17
  123. package/src/skf-create-stack-skill/{steps-c/step-03-rank-and-confirm.md → references/rank-and-confirm.md} +5 -4
  124. package/src/skf-create-stack-skill/{steps-c/step-09-report.md → references/report.md} +3 -3
  125. package/src/skf-create-stack-skill/{steps-c/step-08-validate.md → references/validate.md} +6 -6
  126. package/src/skf-drop-skill/SKILL.md +84 -12
  127. package/src/skf-drop-skill/customize.toml +57 -0
  128. package/src/skf-drop-skill/{steps-c/step-02-execute.md → references/execute.md} +49 -34
  129. package/src/skf-drop-skill/{steps-c/step-04-health-check.md → references/health-check.md} +6 -4
  130. package/src/skf-drop-skill/{steps-c/step-03-report.md → references/report.md} +13 -5
  131. package/src/skf-drop-skill/{steps-c/step-01-select.md → references/select.md} +63 -15
  132. package/src/skf-export-skill/SKILL.md +85 -16
  133. package/src/skf-export-skill/assets/managed-section-format.md +3 -3
  134. package/src/skf-export-skill/assets/snippet-format.md +2 -2
  135. package/src/skf-export-skill/customize.toml +49 -0
  136. package/src/skf-export-skill/{steps-c/step-03-generate-snippet.md → references/generate-snippet.md} +11 -11
  137. package/src/skf-export-skill/{steps-c/step-07-health-check.md → references/health-check.md} +6 -4
  138. package/src/skf-export-skill/{steps-c/step-01-load-skill.md → references/load-skill.md} +11 -49
  139. package/src/skf-export-skill/references/manifest-rebuild.md +68 -0
  140. package/src/skf-export-skill/references/multi-skill-mode.md +38 -0
  141. package/src/skf-export-skill/references/orphan-context-detection.md +75 -0
  142. package/src/skf-export-skill/references/orphan-row-detection.md +102 -0
  143. package/src/skf-export-skill/{steps-c/step-02-package.md → references/package.md} +7 -7
  144. package/src/skf-export-skill/references/preflight-snippet-root-probe.md +79 -0
  145. package/src/skf-export-skill/{steps-c/step-06-summary.md → references/summary.md} +23 -11
  146. package/src/skf-export-skill/{steps-c/step-05-token-report.md → references/token-report.md} +5 -5
  147. package/src/skf-export-skill/{steps-c/step-04-update-context.md → references/update-context.md} +109 -113
  148. package/src/skf-quick-skill/SKILL.md +63 -123
  149. package/src/skf-quick-skill/customize.toml +44 -0
  150. package/src/skf-quick-skill/references/batch-mode.md +102 -0
  151. package/src/skf-quick-skill/{steps-c/step-04-compile.md → references/compile.md} +10 -10
  152. package/src/skf-quick-skill/{steps-c/step-02-ecosystem-check.md → references/ecosystem-check.md} +5 -5
  153. package/src/skf-quick-skill/{steps-c/step-06-finalize.md → references/finalize.md} +7 -7
  154. package/src/skf-quick-skill/{steps-c/step-07-health-check.md → references/health-check.md} +3 -3
  155. package/src/skf-quick-skill/{steps-c/step-03-quick-extract.md → references/quick-extract.md} +5 -5
  156. package/src/skf-quick-skill/references/registry-resolution.md +2 -0
  157. package/src/skf-quick-skill/{steps-c/step-01-resolve-target.md → references/resolve-target.md} +14 -10
  158. package/src/skf-quick-skill/{steps-c/step-05-write-and-validate.md → references/write-and-validate.md} +4 -4
  159. package/src/skf-refine-architecture/SKILL.md +86 -16
  160. package/src/skf-refine-architecture/customize.toml +49 -0
  161. package/src/skf-refine-architecture/{steps-c/step-05-compile.md → references/compile.md} +4 -4
  162. package/src/skf-refine-architecture/{steps-c/step-02-gap-analysis.md → references/gap-analysis.md} +5 -5
  163. package/src/skf-refine-architecture/{steps-c/step-07-health-check.md → references/health-check.md} +6 -4
  164. package/src/skf-refine-architecture/{steps-c/step-04-improvements.md → references/improvements.md} +5 -5
  165. package/src/skf-refine-architecture/references/init.md +144 -0
  166. package/src/skf-refine-architecture/{steps-c/step-03-issue-detection.md → references/issue-detection.md} +5 -5
  167. package/src/skf-refine-architecture/references/refinement-rules.md +2 -0
  168. package/src/skf-refine-architecture/{steps-c/step-06-report.md → references/report.md} +14 -5
  169. package/src/skf-rename-skill/SKILL.md +82 -12
  170. package/src/skf-rename-skill/customize.toml +52 -0
  171. package/src/skf-rename-skill/{steps-c/step-02-execute.md → references/execute.md} +94 -99
  172. package/src/skf-rename-skill/references/health-check.md +30 -0
  173. package/src/skf-rename-skill/references/rebuild-context.md +110 -0
  174. package/src/skf-rename-skill/{steps-c/step-03-report.md → references/report.md} +13 -5
  175. package/src/skf-rename-skill/{steps-c/step-01-select.md → references/select.md} +59 -20
  176. package/src/skf-setup/SKILL.md +35 -35
  177. package/src/skf-setup/customize.toml +33 -0
  178. package/src/skf-setup/{steps-c/step-03-auto-index.md → references/auto-index.md} +10 -18
  179. package/src/skf-setup/{steps-c/step-01b-ccc-index.md → references/ccc-index.md} +16 -31
  180. package/src/skf-setup/{steps-c/step-01-detect-and-tier.md → references/detect-and-tier.md} +23 -10
  181. package/src/skf-setup/{steps-c/step-05-health-check.md → references/health-check.md} +1 -1
  182. package/src/skf-setup/{steps-c/step-04-report.md → references/report.md} +21 -19
  183. package/src/skf-setup/references/tier-rules.md +1 -1
  184. package/src/skf-setup/{steps-c/step-02-write-config.md → references/write-config.md} +14 -13
  185. package/src/skf-test-skill/SKILL.md +77 -15
  186. package/src/skf-test-skill/customize.toml +54 -0
  187. package/src/skf-test-skill/{steps-c/step-04-coherence-check.md → references/coherence-check.md} +37 -73
  188. package/src/skf-test-skill/{steps-c/step-03-coverage-check.md → references/coverage-check.md} +16 -39
  189. package/src/skf-test-skill/{steps-c/step-02-detect-mode.md → references/detect-mode.md} +4 -26
  190. package/src/skf-test-skill/{steps-c/step-04b-external-validators.md → references/external-validators.md} +6 -28
  191. package/src/skf-test-skill/references/health-check.md +14 -0
  192. package/src/skf-test-skill/{steps-c/step-01-init.md → references/init.md} +21 -37
  193. package/src/skf-test-skill/references/migration-section-rules.md +4 -2
  194. package/src/skf-test-skill/{steps-c/step-06-report.md → references/report.md} +41 -51
  195. package/src/skf-test-skill/{steps-c/step-05-score.md → references/score.md} +26 -43
  196. package/src/skf-test-skill/references/scoring-rules.md +8 -6
  197. package/src/skf-test-skill/references/source-access-protocol.md +7 -5
  198. package/src/skf-test-skill/scripts/compute-score.py +88 -17
  199. package/src/skf-test-skill/templates/test-report-template.md +13 -13
  200. package/src/skf-update-skill/SKILL.md +23 -14
  201. package/src/skf-update-skill/customize.toml +44 -0
  202. package/src/skf-update-skill/{steps-c/step-02-detect-changes.md → references/detect-changes.md} +176 -68
  203. package/src/skf-update-skill/references/health-check.md +32 -0
  204. package/src/skf-update-skill/{steps-c/step-01-init.md → references/init.md} +56 -8
  205. package/src/skf-update-skill/references/manual-section-rules.md +4 -0
  206. package/src/skf-update-skill/references/merge-conflict-rules.md +4 -0
  207. package/src/skf-update-skill/{steps-c/step-04-merge.md → references/merge.md} +8 -8
  208. package/src/skf-update-skill/{steps-c/step-03-re-extract.md → references/re-extract.md} +53 -44
  209. package/src/skf-update-skill/references/remote-source-resolution.md +5 -1
  210. package/src/skf-update-skill/references/report.md +214 -0
  211. package/src/skf-update-skill/{steps-c/step-05-validate.md → references/validate.md} +5 -5
  212. package/src/skf-update-skill/{steps-c/step-06-write.md → references/write.md} +73 -51
  213. package/src/skf-verify-stack/SKILL.md +89 -17
  214. package/src/skf-verify-stack/assets/feasibility-report-template.md +4 -4
  215. package/src/skf-verify-stack/customize.toml +50 -0
  216. package/src/skf-verify-stack/references/coverage-patterns.md +2 -2
  217. package/src/skf-verify-stack/{steps-c/step-02-coverage.md → references/coverage.md} +13 -9
  218. package/src/skf-verify-stack/{steps-c/step-07-health-check.md → references/health-check.md} +7 -5
  219. package/src/skf-verify-stack/references/init.md +170 -0
  220. package/src/skf-verify-stack/references/integration-verification-rules.md +1 -1
  221. package/src/skf-verify-stack/{steps-c/step-03-integrations.md → references/integrations.md} +18 -14
  222. package/src/skf-verify-stack/{steps-c/step-06-report.md → references/report.md} +27 -42
  223. package/src/skf-verify-stack/{steps-c/step-04-requirements.md → references/requirements.md} +13 -9
  224. package/src/skf-verify-stack/{steps-c/step-05-synthesize.md → references/synthesize.md} +14 -10
  225. package/tools/validate-docs-drift.js +1 -1
  226. package/src/skf-refine-architecture/steps-c/step-01-init.md +0 -136
  227. package/src/skf-rename-skill/steps-c/step-04-health-check.md +0 -22
  228. package/src/skf-test-skill/steps-c/step-07-health-check.md +0 -25
  229. package/src/skf-update-skill/steps-c/step-07-report.md +0 -148
  230. package/src/skf-update-skill/steps-c/step-08-health-check.md +0 -22
  231. package/src/skf-verify-stack/steps-c/step-01-init.md +0 -178
@@ -30,7 +30,7 @@
30
30
  "name": "skill-forge",
31
31
  "source": "./",
32
32
  "description": "Evidence-based agent skills compiler with progressive capability tiers (Quick/Forge/Forge+/Deep).",
33
- "version": "1.4.1",
33
+ "version": "1.5.1",
34
34
  "author": {
35
35
  "name": "Armel"
36
36
  },
package/README.md CHANGED
@@ -181,14 +181,6 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
181
181
 
182
182
  Past releases are documented in [CHANGELOG.md](CHANGELOG.md).
183
183
 
184
- ## Versioning & Stability
185
-
186
- The v1.0.0 public API contract is documented in [docs/_internal/STABILITY.md](docs/_internal/STABILITY.md).
187
-
188
- ## Release Process
189
-
190
- Maintainers: see [docs/_internal/RELEASING.md](docs/_internal/RELEASING.md) for branch-protection rules, required status checks, the [`release` environment with required-reviewer gate](docs/_internal/RELEASING.md#release-environment), the [npm Trusted Publisher registration](docs/_internal/RELEASING.md#npm-trusted-publisher) (OIDC-backed publish, auto-provenance), and the [rollback playbook](docs/_internal/RELEASING.md#rollback-playbook) covering seven failure scenarios.
191
-
192
184
  ## License
193
185
 
194
186
  MIT License — see [LICENSE](LICENSE) for details.
@@ -26,7 +26,7 @@
26
26
  # Enforced two ways: (1) release.yaml bumps this line in the same commit
27
27
  # as package.json + marketplace.json on every release; (2) validate-docs-drift.js
28
28
  # cross-checks this value against package.json.version and fails on mismatch.
29
- skf_version: "1.4.1"
29
+ skf_version: "1.5.1"
30
30
 
31
31
  # Path to the oh-my-skills repo, resolved relative to this repo's root.
32
32
  # Override at runtime with the OMS environment variable if oh-my-skills
@@ -86,7 +86,7 @@ SKF supports the Node.js major versions declared in `package.json` `engines.node
86
86
  The following surfaces are explicitly excluded from the v1.0.0 contract. Changes to any of these may land in any release — patch, minor, or major — without constituting a "breaking change" from a SemVer perspective. Downstream consumers SHOULD NOT pin against these surfaces.
87
87
 
88
88
  - **`tools/cli/lib/*` internal helper modules** — implementation detail of the CLI; not a library. Any refactor that preserves the observable CLI surface and install layout above is allowed.
89
- - **Internal structure of workflow step files under `src/skf-*/steps-c/`** — the workflow authoring format is an SKF-internal authoring surface; step numbering, file names, and prose can change.
89
+ - **Internal structure of workflow step files under `src/skf-*/references/`** — the workflow authoring format is an SKF-internal authoring surface; step numbering, file names, and prose can change.
90
90
  - **`_bmad/_memory/forger-sidecar/*.yaml` file schemas** — Ferris sidecar state. Stable as a runtime contract between SKF versions during one install's lifetime (so `skf update` works), but not a downstream-consumable schema.
91
91
  - **Ferris agent persona prose and menu wording** — the in-product agent persona can be rephrased or restructured at any time.
92
92
  - **Exact chalk styling / ANSI color choices in command output** — stylistic; see the output-format bucket above for what IS committed.
@@ -22,7 +22,7 @@ Each workflow directory contains these files, and each has a specific job:
22
22
  | File | What it does | When it loads |
23
23
  |---------------------------|---------------------------------------------------------------------------------------------------------------------|---------------------------------------------------|
24
24
  | `SKILL.md` | Human-readable entry point — goals, role definition, initialization sequence, invocation contract, routes to first step | Entry point per workflow |
25
- | `steps-c/*.md` | **Create** steps — primary execution, 4–10 sequential files per workflow (the last one always chains to the shared health check) | One at a time (just-in-time) |
25
+ | `references/*.md` | **Create** steps — primary execution, 4–10 sequential files per workflow (the last one always chains to the shared health check) | One at a time (just-in-time) |
26
26
  | `references/*.md` | Workflow-specific reference data — rules, patterns, protocols | Read by steps on demand |
27
27
  | `assets/*.md` | Workflow-specific output formats — schemas, templates, heuristics | Read by steps on demand |
28
28
  | `templates/*.md` | Output skeletons with placeholder vars — steps fill these in to produce the final artifact | Read by steps when generating output |
@@ -41,7 +41,7 @@ Each workflow directory contains these files, and each has a specific job:
41
41
  flowchart LR
42
42
  U[User] --> A[Agent Persona]
43
43
  A --> W[Workflow Entry: SKILL.md]
44
- W --> S[Step Files: steps-c/]
44
+ W --> S[Step Files: references/]
45
45
  S --> K[Knowledge Fragments<br/>skf-knowledge-index.csv → knowledge/*.md]
46
46
  S --> D[References & Assets<br/>references/*.md, assets/*.md, templates/*.md]
47
47
  S --> P[Scripts<br/>scripts/*.py, shared/scripts/*.py]
package/docs/examples.md CHANGED
@@ -210,7 +210,7 @@ No source code to clone — only API documentation. Example: you're integrating
210
210
  # When asked for target version, specify: 2025-04-30.basil
211
211
  # Ferris confirms your doc URLs match that API version
212
212
  @Ferris CS
213
- # step-03 skips (no source to clone), step-03c fetches docs via doc_fetcher
213
+ # step 3 skips (no source to clone), step 3c fetches docs via doc_fetcher
214
214
  # All content is T3 [EXT:url] confidence. source_authority: community
215
215
  ```
216
216
 
package/docs/workflows.md CHANGED
@@ -361,7 +361,7 @@ You can also set `headless_mode: true` in your forge preferences (`_bmad/_memory
361
361
  SKF_SETUP_RESULT_JSON: {"skf_setup":{"tier":"Deep","previous_tier":"Forge","tier_changed":true,"tools":{...},"tools_added":[...],"tools_removed":[],"config_path":"...","ccc_index":{...},"files_written":[...],"tier_override_active":false,"tier_override_invalid":false,"require_tier_satisfied":null,"warnings":[],"error":null}}
362
362
  ```
363
363
 
364
- Parent skills and CI pipelines `grep` one line out of the workflow log to learn the outcome — no ASCII-art parsing, no race against the [`forge-tier.yaml`](https://github.com/armelhbobdad/bmad-module-skill-forge/blob/main/src/skf-setup/steps-c/step-02-write-config.md) writer. The envelope schema is versioned at [`src/shared/scripts/schemas/skf-setup-result-envelope.v1.json`](https://github.com/armelhbobdad/bmad-module-skill-forge/blob/main/src/shared/scripts/schemas/skf-setup-result-envelope.v1.json) and asserted against on every emit.
364
+ Parent skills and CI pipelines `grep` one line out of the workflow log to learn the outcome — no ASCII-art parsing, no race against the [`forge-tier.yaml`](https://github.com/armelhbobdad/bmad-module-skill-forge/blob/main/src/skf-setup/references/write-config.md) writer. The envelope schema is versioned at [`src/shared/scripts/schemas/skf-setup-result-envelope.v1.json`](https://github.com/armelhbobdad/bmad-module-skill-forge/blob/main/src/shared/scripts/schemas/skf-setup-result-envelope.v1.json) and asserted against on every emit.
365
365
 
366
366
  **Exception — `/skf-quick-skill` headless emits structured progress + result envelopes.** Headless `/skf-quick-skill` runs are first-class building blocks for batch automators. Three operational contracts beyond per-gate auto-proceed:
367
367
 
@@ -386,13 +386,13 @@ Parent skills and CI pipelines `grep` one line out of the workflow log to learn
386
386
  | 6 | compile-cancelled |
387
387
  | 7 | finalize-blocked |
388
388
 
389
- 3. **Error-variant result contract on every HARD HALT.** A `SKF_QUICK_SKILL_RESULT_JSON: {…}` envelope is emitted on `stderr` (always) and copied to `{skill_package}/quick-skill-result-latest.json` when the skill package is known (HALTs at step-05 §1 onward). The schema and full population rules live in [`src/skf-quick-skill/SKILL.md`](https://github.com/armelhbobdad/bmad-module-skill-forge/blob/main/src/skf-quick-skill/SKILL.md) § "Result Contract on HARD HALT".
389
+ 3. **Error-variant result contract on every HARD HALT.** A `SKF_QUICK_SKILL_RESULT_JSON: {…}` envelope is emitted on `stderr` (always) and copied to `{skill_package}/quick-skill-result-latest.json` when the skill package is known (HALTs at step 5 §1 onward). The schema and full population rules live in [`src/skf-quick-skill/SKILL.md`](https://github.com/armelhbobdad/bmad-module-skill-forge/blob/main/src/skf-quick-skill/SKILL.md) § "Result Contract on HARD HALT".
390
390
 
391
391
  **Batch mode (`--batch <file>`).** Drives N targets through the full pipeline (steps 1–7 each) in sequence. Input format: one target per line, `#` comments and blank lines ignored, optional per-line modifiers `language=<lang>` and `scope=<path>`. Per-target output lands in `{skill_package}/` as today; an aggregated summary writes to `{skills_output_folder}/_batch/quick-skill-batch-{ts}.json` (with `quick-skill-batch-latest.json` copy). Per-target boundary events (`{"batch":N,"target":"…","status":"start|done|fail",…}`) and a final `{"batch_summary":true,…}` event extend the per-step event stream above. Full input grammar, summary schema, and exit-code semantics in [`src/skf-quick-skill/SKILL.md`](https://github.com/armelhbobdad/bmad-module-skill-forge/blob/main/src/skf-quick-skill/SKILL.md) § "Batch Mode".
392
392
 
393
393
  **Exception — `/skf-brief-skill` headless emits a final result envelope and supports presets.** Headless `/skf-brief-skill` is a first-class building block for scripted brief generation (e.g. seeding briefs for N SaaS SDKs that share scope/authority defaults). Three operational contracts beyond per-gate auto-proceed:
394
394
 
395
- 1. **Pre-supplied inputs replace prompts.** Headless args are consumed at step-01's GATE in place of the interactive menus: `target_repo`, `skill_name`, `target_version`, `language`, `source_type`, `source_authority`, `doc_urls`, `scope_type`, `scripts_intent`, `force`, `preset`. Required-arg shape depends on `source_type` (`target_repo` + `skill_name` for source-backed; `doc_urls` + `skill_name` for `docs-only`). Absent `source_authority` and `scope_type` are NOT guessed — they're resolved by signal-driven detection (`gh api user` vs. repo owner for authority; the 5-rule heuristic ladder for scope). Full grammar in [`src/skf-brief-skill/references/headless-args.md`](https://github.com/armelhbobdad/bmad-module-skill-forge/blob/main/src/skf-brief-skill/references/headless-args.md).
395
+ 1. **Pre-supplied inputs replace prompts.** Headless args are consumed at step 1's GATE in place of the interactive menus: `target_repo`, `skill_name`, `target_version`, `language`, `source_type`, `source_authority`, `doc_urls`, `scope_type`, `scripts_intent`, `force`, `preset`. Required-arg shape depends on `source_type` (`target_repo` + `skill_name` for source-backed; `doc_urls` + `skill_name` for `docs-only`). Absent `source_authority` and `scope_type` are NOT guessed — they're resolved by signal-driven detection (`gh api user` vs. repo owner for authority; the 5-rule heuristic ladder for scope). Full grammar in [`src/skf-brief-skill/references/headless-args.md`](https://github.com/armelhbobdad/bmad-module-skill-forge/blob/main/src/skf-brief-skill/references/headless-args.md).
396
396
 
397
397
  2. **Structured exit-code map.** Every HARD HALT exits with a stable code so pipelines branch on the failure class without grepping message text:
398
398
 
@@ -405,9 +405,9 @@ Parent skills and CI pipelines `grep` one line out of the workflow log to learn
405
405
  | 5 | overwrite-cancelled |
406
406
  | 6 | user-cancelled |
407
407
 
408
- 3. **Final result envelope on every terminal exit.** Step-05 emits a single-line `SKF_BRIEF_RESULT_JSON: {…}` envelope on **stdout** before chaining to step-06 on success; every HARD HALT emits the same envelope shape on **stderr** with `status: "error"` and a typed `halt_reason` (`input-missing`, `input-invalid`, `forge-tier-missing`, `target-inaccessible`, `gh-auth-failed`, `write-failed`, `overwrite-cancelled`, `user-cancelled`). Full envelope schema and population rules in [`src/skf-brief-skill/SKILL.md`](https://github.com/armelhbobdad/bmad-module-skill-forge/blob/main/src/skf-brief-skill/SKILL.md) § "Result Contract (Headless)".
408
+ 3. **Final result envelope on every terminal exit.** Step-05 emits a single-line `SKF_BRIEF_RESULT_JSON: {…}` envelope on **stdout** before chaining to step 6 on success; every HARD HALT emits the same envelope shape on **stderr** with `status: "error"` and a typed `halt_reason` (`input-missing`, `input-invalid`, `forge-tier-missing`, `target-inaccessible`, `gh-auth-failed`, `write-failed`, `overwrite-cancelled`, `user-cancelled`). Full envelope schema and population rules in [`src/skf-brief-skill/SKILL.md`](https://github.com/armelhbobdad/bmad-module-skill-forge/blob/main/src/skf-brief-skill/SKILL.md) § "Result Contract (Headless)".
409
409
 
410
- **Presets (`--preset <name>`).** Loads `{sidecar_path}/brief-presets/{name}.yaml` and merges its keys as defaults at step-01 §8; explicit headless args override preset values. The preset file is YAML containing any subset of the headless args above; unknown fields are ignored with a warning. Useful for repeated patterns — e.g. briefing 5 SaaS SDKs that all share `source_authority=community`, `scope_type=full-library`, `scripts_intent=skip`.
410
+ **Presets (`--preset <name>`).** Loads `{sidecar_path}/brief-presets/{name}.yaml` and merges its keys as defaults at step 1 §8; explicit headless args override preset values. The preset file is YAML containing any subset of the headless args above; unknown fields are ignored with a warning. Useful for repeated patterns — e.g. briefing 5 SaaS SDKs that all share `source_authority=community`, `scope_type=full-library`, `scripts_intent=skip`.
411
411
 
412
412
  ---
413
413
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "bmad-module-skill-forge",
4
- "version": "1.4.1",
4
+ "version": "1.5.1",
5
5
  "description": "BMAD module — Turn code and docs into instructions AI agents can actually follow. Progressive capability tiers (Quick/Forge/Forge+/Deep).",
6
6
  "keywords": [
7
7
  "bmad",
@@ -53,7 +53,7 @@
53
53
  "test:cli": "node test/test-cli-integration.js",
54
54
  "test:install": "node test/test-installation-components.js",
55
55
  "test:knowledge": "node test/test-knowledge-base.js",
56
- "test:python": "uv run --with pytest --with pyyaml pytest test/test-compute-score-contract.py test/test-skf-preflight.py test/test-skf-skill-inventory.py test/test-skf-validate-output.py test/test-skf-validate-frontmatter.py test/test-skf-manifest-ops.py test/test-skf-rebuild-managed-sections.py test/test-skf-severity-classify.py test/test-skf-structural-diff.py test/test-skf-detect-tools.py test/test-skf-forge-tier-rw.py test/test-skf-emit-result-envelope.py test/test-skf-qmd-classify-collections.py test/test-skf-merge-ccc-exclusions.py test/test-skf-resolve-package.py test/test-skf-extract-public-api.py test/test-skf-render-quick-metadata.py test/test-skf-validate-brief-inputs.py test/test-skf-emit-brief-result-envelope.py test/test-skf-write-skill-brief.py test/test-skf-detect-workspaces.py test/test-skf-recommend-scope-type.py test/test-skf-detect-language.py -v",
56
+ "test:python": "uv run --with pytest --with pyyaml --with jsonschema pytest test/test-compute-score-contract.py test/test-skf-preflight.py test/test-skf-skill-inventory.py test/test-skf-validate-output.py test/test-skf-validate-frontmatter.py test/test-skf-manifest-ops.py test/test-skf-rebuild-managed-sections.py test/test-skf-severity-classify.py test/test-skf-structural-diff.py test/test-skf-detect-tools.py test/test-skf-forge-tier-rw.py test/test-skf-emit-result-envelope.py test/test-skf-qmd-classify-collections.py test/test-skf-merge-ccc-exclusions.py test/test-skf-resolve-package.py test/test-skf-extract-public-api.py test/test-skf-render-quick-metadata.py test/test-skf-validate-brief-inputs.py test/test-skf-emit-brief-result-envelope.py test/test-skf-write-skill-brief.py test/test-skf-detect-workspaces.py test/test-skf-recommend-scope-type.py test/test-skf-detect-language.py test/test-skf-description-guard.py test/test-skf-detect-scripts-assets.py test/test-skf-hash-content.py test/test-skf-validate-brief-schema.py test/test-skf-check-workspace-drift.py test/test-skf-update-active-symlink.py test/test-skf-build-change-manifest.py test/test-skf-provenance-gap-dispatch.py test/test-skf-resolve-authoritative-files.py test/test-skf-scan-manifests.py test/test-skf-pair-intersect.py test/test-skf-enumerate-stack-skills.py test/test-skf-compare-file-hashes.py test/test-skf-load-provenance.py test/test-skf-scan-skill-md-structure.py test/test-skf-disqualify-candidates.py test/test-skf-chain-reachability.py -v",
57
57
  "test:schemas": "node test/test-agent-schema.js",
58
58
  "test:workflow": "node test/test-workflow-state.js",
59
59
  "validate:refs": "node tools/validate-file-refs.js --strict",
package/src/README.md CHANGED
@@ -16,7 +16,7 @@ src/
16
16
  │ └── ...
17
17
  ├── skf-{name}/ # 13 workflow skills (one directory each)
18
18
  │ ├── SKILL.md # Skill entry point (overview, stages, invocation contract)
19
- │ ├── steps-c/ # Sequential step files
19
+ │ ├── references/ # Sequential step files
20
20
  │ ├── references/ # Rules, patterns, protocols (decision-making)
21
21
  │ ├── assets/ # Schemas, output formats
22
22
  │ └── templates/ # Output skeletons (used by some skills)
@@ -43,7 +43,7 @@ Returns: list of `{file, score, snippet}` entries ranked by semantic relevance t
43
43
 
44
44
  **Resolves to:** Check `ccc_index.status` in forge-tier.yaml. If `"none"` or the indexed_path does not match, run `cd {path} && ccc init` then `ccc index` and update forge-tier.yaml. Note: `ccc init` takes no positional arguments — it initializes the index for the current working directory.
45
45
 
46
- **Usage context:** Called by setup step-01b to ensure the project root is indexed. Called lazily by extraction steps when `ccc_index.status` is `"none"` but ccc is available.
46
+ **Usage context:** Called by setup step 1b to ensure the project root is indexed. Called lazily by extraction steps when `ccc_index.status` is `"none"` but ccc is available.
47
47
 
48
48
  ### `ccc_bridge.status()`
49
49
 
@@ -51,7 +51,7 @@ Returns: list of `{file, score, snippet}` entries ranked by semantic relevance t
51
51
  1. `ccc --help` — confirms binary exists (exit 0) AND output contains the `CocoIndex Code` identity marker (rejects unrelated `ccc`-named binaries shadowing PATH)
52
52
  2. `ccc doctor` — confirms daemon is running, extracts version string, validates embedding model
53
53
 
54
- **Usage context:** Called exclusively by setup step-01 during tool detection. Downstream workflows read the result from forge-tier.yaml — they do not re-verify.
54
+ **Usage context:** Called exclusively by setup step 1 during tool detection. Downstream workflows read the result from forge-tier.yaml — they do not re-verify.
55
55
 
56
56
  ## Confidence
57
57
 
@@ -67,7 +67,7 @@ The ccc search is invisible in the output artifact. A Forge+ skill's citations a
67
67
 
68
68
  ### When Indexing Happens
69
69
 
70
- 1. **setup step-01b:** Indexes the project root when setup runs. This is the primary indexing point.
70
+ 1. **setup step 1b:** Indexes the project root when setup runs. This is the primary indexing point.
71
71
  2. **Workflow discovery steps:** If `ccc_index.status` is `"stale"` or `"none"`, discovery steps trigger a re-index and warn the user. They do not block.
72
72
  3. **ccc daemon:** Incremental indexing means re-indexing unchanged files is a near-no-op.
73
73
 
@@ -81,7 +81,7 @@ The ccc search is invisible in the output artifact. A Forge+ skill's citations a
81
81
 
82
82
  CCC stores its configuration at `{project-root}/.cocoindex_code/settings.yml`. This file contains `exclude_patterns` and `include_patterns` arrays in glob format. `ccc init` creates the file with sensible defaults (excludes `node_modules`, `__pycache__`, hidden dirs, etc.).
83
83
 
84
- **SKF infrastructure exclusions:** setup step-01b appends SKF-specific exclusion patterns after `ccc init` creates the default config. These patterns prevent indexing of framework and output directories that have zero value for source extraction:
84
+ **SKF infrastructure exclusions:** setup step 1b appends SKF-specific exclusion patterns after `ccc init` creates the default config. These patterns prevent indexing of framework and output directories that have zero value for source extraction:
85
85
 
86
86
  | Pattern | Purpose |
87
87
  |---------|---------|
@@ -98,13 +98,13 @@ The configured exclusion patterns are stored in `ccc_index.exclude_patterns` in
98
98
 
99
99
  ### Deferred Discovery (Remote Sources)
100
100
 
101
- For remote repository sources (GitHub URLs), CCC cannot operate during step-02b because no local code exists yet. The workspace clone or ephemeral clone happens in step-03. To provide CCC pre-ranking for remote sources:
101
+ For remote repository sources (GitHub URLs), CCC cannot operate during step 2b because no local code exists yet. The workspace clone or ephemeral clone happens in step 3. To provide CCC pre-ranking for remote sources:
102
102
 
103
- 1. **step-02b:** Detects remote source, sets `{ccc_discovery: []}`, displays deferred message
104
- 2. **step-03:** After source resolution succeeds, detects the deferred scenario (`tools.ccc == true AND {ccc_discovery} is empty AND remote_clone_path is set AND tier is Forge+/Deep`)
105
- 3. **step-03 (workspace fast path):** If `{remote_clone_path}/.cocoindex_code/` already exists (persisted workspace index), skips init/index and uses `ccc search --refresh` — CCC daemon re-indexes only if files changed since last index. This is near-instant for unchanged repos.
106
- 4. **step-03 (first-time path):** If no existing CCC index, runs `cd {remote_clone_path} && ccc init`, applies standard build/dependency exclusions (node_modules, dist, .git, vendor, etc.) to `settings.yml`, then runs `ccc index`. Brief-specific `include_patterns`/`exclude_patterns` are NOT written to `settings.yml` — the CCC index is general-purpose. Filtering happens at search result time.
107
- 5. **step-03:** Executes CCC search and populates `{ccc_discovery}` before AST extraction begins
103
+ 1. **step 2b:** Detects remote source, sets `{ccc_discovery: []}`, displays deferred message
104
+ 2. **step 3:** After source resolution succeeds, detects the deferred scenario (`tools.ccc == true AND {ccc_discovery} is empty AND remote_clone_path is set AND tier is Forge+/Deep`)
105
+ 3. **step 3 (workspace fast path):** If `{remote_clone_path}/.cocoindex_code/` already exists (persisted workspace index), skips init/index and uses `ccc search --refresh` — CCC daemon re-indexes only if files changed since last index. This is near-instant for unchanged repos.
106
+ 4. **step 3 (first-time path):** If no existing CCC index, runs `cd {remote_clone_path} && ccc init`, applies standard build/dependency exclusions (node_modules, dist, .git, vendor, etc.) to `settings.yml`, then runs `ccc index`. Brief-specific `include_patterns`/`exclude_patterns` are NOT written to `settings.yml` — the CCC index is general-purpose. Filtering happens at search result time.
107
+ 5. **step 3:** Executes CCC search and populates `{ccc_discovery}` before AST extraction begins
108
108
 
109
109
  For workspace repos, the CCC index persists at `{workspace_repo_path}/.cocoindex_code/` and is reused across forges, projects, and sessions. For ephemeral fallback clones, the index is not registered in `ccc_index_registry` — the clone is deleted after extraction.
110
110
 
@@ -114,7 +114,7 @@ ccc_index and qmd_collections are **orthogonal**:
114
114
  - `ccc_index` in forge-tier.yaml tracks the persistent source code index (one per project)
115
115
  - `qmd_collections[]` in forge-tier.yaml tracks per-skill workflow artifact collections
116
116
  - ccc indexes source code for semantic search; QMD indexes curated artifacts for temporal/knowledge search
117
- - The janitor role for QMD (setup step-03) operates independently of ccc_index
117
+ - The janitor role for QMD (setup step 3) operates independently of ccc_index
118
118
 
119
119
  ## Query Volume Bounds
120
120
 
@@ -133,7 +133,7 @@ To prevent excessive daemon calls, workflow steps cap ccc queries:
133
133
  - Listing ccc as "unavailable" in reports for Quick/Forge tiers — ccc is a Forge+ capability, not something Quick/Forge tiers are missing
134
134
  - Indexing without configuring exclusions — for project root indexes, apply SKF exclusions (framework/output directories); for workspace repo indexes, apply standard build artifact exclusions (node_modules, dist, .git, etc.)
135
135
  - Writing brief-specific `exclude_patterns` to a workspace repo's `settings.yml` — workspace indexes are general-purpose and serve multiple briefs. Apply brief patterns at search result time, not index time. (Exception: ephemeral fallback clones are single-use, so brief exclusions may be applied to their `settings.yml` to reduce indexing time.)
136
- - Skipping CCC discovery for remote sources without deferring to step-03 — remote repos deserve the same pre-ranking as local sources
136
+ - Skipping CCC discovery for remote sources without deferring to step 3 — remote repos deserve the same pre-ranking as local sources
137
137
 
138
138
  ## Related Fragments
139
139
 
@@ -51,10 +51,10 @@ The `status` field is only present when QMD embed verification fails during coll
51
51
 
52
52
  | Type | Producer | Content | Primary Consumers |
53
53
  | --- | --- | --- | --- |
54
- | `extraction` | create-skill step-07 | Compiled SKILL.md, references, context-snippet — structured, confidence-rated exports | audit-skill (drift detection), update-skill (T2 enrichment) |
55
- | `brief` | brief-skill step-05 | skill-brief.yaml — intent, scope, target repository metadata | Portfolio-level search (cross-skill deduplication) |
56
- | `temporal` | create-skill step-03b | GitHub issues, PRs, releases, changelogs — historical and planned context at T2 confidence | step-04 enrichment (temporal annotations per exported function) |
57
- | `docs` | create-skill step-03c | Fetched external documentation — API references, guides, usage examples (T3 confidence) | step-04 enrichment (cross-reference doc context with source-extracted functions) |
54
+ | `extraction` | create-skill step 7 | Compiled SKILL.md, references, context-snippet — structured, confidence-rated exports | audit-skill (drift detection), update-skill (T2 enrichment) |
55
+ | `brief` | brief-skill step 5 | skill-brief.yaml — intent, scope, target repository metadata | Portfolio-level search (cross-skill deduplication) |
56
+ | `temporal` | create-skill step 3b | GitHub issues, PRs, releases, changelogs — historical and planned context at T2 confidence | step 4 enrichment (temporal annotations per exported function) |
57
+ | `docs` | create-skill step 3c | Fetched external documentation — API references, guides, usage examples (T3 confidence) | step 4 enrichment (cross-reference doc context with source-extracted functions) |
58
58
 
59
59
  ### Lifecycle
60
60
 
@@ -112,7 +112,7 @@ The `ccc_index_registry` array in forge-tier.yaml is a **parallel but separate**
112
112
  | **What is indexed** | Curated workflow artifacts (SKILL.md, briefs, temporal data) | Source code (the actual codebase) |
113
113
  | **Index engine** | QMD (BM25 + optional vector search) | cocoindex-code (AST + vector embeddings) |
114
114
  | **Lifecycle** | Per-skill: created by create-skill, consumed by audit/update-skill | Per-project: created by setup, verified by create-skill |
115
- | **Janitor** | setup step-03 (orphan/stale QMD collection cleanup) | setup step-03 section 5b (stale path cleanup) |
115
+ | **Janitor** | setup step 3 (orphan/stale QMD collection cleanup) | setup step 3 section 5b (stale path cleanup) |
116
116
  | **Availability** | Deep tier only | Forge+ and Deep tiers |
117
117
 
118
118
  These registries are orthogonal — they never reference each other, and their janitor sections operate independently.
@@ -90,7 +90,7 @@ For each genuine finding, present it in this format:
90
90
  |-------|-------|
91
91
  | **Severity** | `bug` / `friction` / `gap` |
92
92
  | **Workflow** | {workflow name} |
93
- | **Step File** | `src/skf-{workflow}/steps-c/{step-file-path}` |
93
+ | **Step File** | `src/skf-{workflow}/references/{step-file-path}` |
94
94
  | **Section** | {the specific section or instruction number — use a stable section heading slug, not line numbers} |
95
95
  | **Fingerprint** | `fp-{7-hex}` — first 7 hex chars of `sha1("{severity}|{workflow}|{step_file}|{section-slug}")` |
96
96
 
@@ -223,7 +223,7 @@ After the issue is created, write the fingerprint → issue-url mapping to the s
223
223
  {workflow name, e.g. `skf-create-skill`}
224
224
 
225
225
  ## Step File
226
- `src/skf-{workflow}/steps-c/step-NN-name.md`
226
+ `src/skf-{workflow}/references/step-NN-name.md`
227
227
 
228
228
  ## Severity
229
229
  `{bug | friction | gap}`
@@ -246,7 +246,7 @@ After the issue is created, write the fingerprint → issue-url mapping to the s
246
246
 
247
247
  ## Actual
248
248
  <!-- ONE sentence. What did you observe instead? -->
249
- {e.g. No staging path specified, so artifacts were written to `skills/{name}/` and step-07 had to reorganize them.}
249
+ {e.g. No staging path specified, so artifacts were written to `skills/{name}/` and step 7 had to reorganize them.}
250
250
 
251
251
  ## Evidence
252
252
  <!-- Bulleted `file:line` citations. 2-5 bullets. No narrative prose. -->
@@ -255,11 +255,11 @@ After the issue is created, write the fingerprint → issue-url mapping to the s
255
255
 
256
256
  ## Impact
257
257
  <!-- ONE sentence. What did this cost in THIS session? -->
258
- {e.g. 50KB of artifacts written to the wrong path; step-07 required a file-move pass.}
258
+ {e.g. 50KB of artifacts written to the wrong path; step 7 required a file-move pass.}
259
259
 
260
260
  ## Suggested Fix
261
261
  <!-- ONE recommended change. 1-3 sentences. Do NOT list multiple options here. -->
262
- {e.g. Add a rule to step-05 naming `_bmad-output/{skill-name}/` as the staging directory used by step-06 validation.}
262
+ {e.g. Add a rule to step 5 naming `_bmad-output/{skill-name}/` as the staging directory used by step 6 validation.}
263
263
 
264
264
  <details>
265
265
  <summary>Alternatives considered (optional)</summary>
@@ -0,0 +1,100 @@
1
+ # Description Guard Protocol
2
+
3
+ ## Overview
4
+
5
+ External validators (`skill-check check --fix`, `skill-check split-body`, and any future tool that may rewrite SKILL.md frontmatter) occasionally replace, truncate, or otherwise mutate the `description` field — sometimes substituting a generic version, sometimes re-introducing angle-bracket tokens that earlier sanitization removed.
6
+
7
+ The on-disk description is **authoritative**: it has been compiled (in `skf-create-skill`) or merged (in `skf-update-skill`) with deliberate trigger-optimization. Losing it to a tool's well-meaning rewrite breaks agent discovery quality and can re-introduce the angle-bracket failure mode that breaks tessl on the next run.
8
+
9
+ Any tool invocation that may touch SKILL.md must run inside the four-phase guard below. Workflows invoke the deterministic phases (1, 3, 4) via `src/shared/scripts/skf-description-guard.py`; the LLM only performs phase 2 (the tool call itself).
10
+
11
+ ## The Four-Phase Guard
12
+
13
+ ### 1. Capture
14
+
15
+ Before invoking the tool, snapshot the on-disk `description` value:
16
+
17
+ ```bash
18
+ uv run {project-root}/src/shared/scripts/skf-description-guard.py \
19
+ capture <skill-md-path>
20
+ ```
21
+
22
+ Output JSON:
23
+
24
+ ```json
25
+ {
26
+ "description": "the snapshotted value",
27
+ "schema_hash": "sha256:..."
28
+ }
29
+ ```
30
+
31
+ Stash the `description` value in workflow context as `guarded_description`. Also keep the in-context copy synced with the on-disk pre-call state.
32
+
33
+ ### 2. Execute
34
+
35
+ Run the tool as specified in its section. The LLM performs this step normally — `skill-check check --fix`, `skill-check split-body`, or whatever is documented in the calling stage.
36
+
37
+ ### 3 + 4. Verify and Restore
38
+
39
+ After the tool completes, run:
40
+
41
+ ```bash
42
+ uv run {project-root}/src/shared/scripts/skf-description-guard.py \
43
+ verify-restore <skill-md-path> \
44
+ --captured-description "{guarded_description}"
45
+ ```
46
+
47
+ The script:
48
+
49
+ 1. Re-reads on-disk `description`
50
+ 2. Compares against `guarded_description` using **token-stream equality** — split each string on whitespace, compare resulting token lists element-by-element
51
+ 3. If diverged: atomically rewrites the frontmatter `description` field with `guarded_description`
52
+
53
+ Output JSON:
54
+
55
+ ```json
56
+ {
57
+ "diverged": true|false,
58
+ "restored": true|false,
59
+ "diff_kind": "none|whitespace-only|replaced|truncated|deleted",
60
+ "current_description": "what was on disk before any restore"
61
+ }
62
+ ```
63
+
64
+ If `restored == true`, also update the in-context copy of `description` to match `guarded_description` so subsequent stages do not work from a stale tool-mutated version. Record `description_guard_restored: true` (with the tool name) in workflow context for the evidence report.
65
+
66
+ ## Why Token-Stream Comparison
67
+
68
+ Token-stream comparison is the documented sweet spot between two failure modes:
69
+
70
+ - **Looser fuzzy matching** would let a tool swap one word past the guard (e.g., replace "compile" with "build").
71
+ - **Naive whitespace-normalized equality** would trip on a tool that collapses `"foo bar"` → `"foo bar"` (cosmetic whitespace fix), forcing unnecessary restore writes.
72
+
73
+ Splitting on whitespace and comparing token lists catches replaced words, truncation, deletion, and angle-bracket re-introduction while ignoring trailing newlines, re-wrapped quoted strings, and collapsed inner runs.
74
+
75
+ ## What Counts as Divergence
76
+
77
+ - **`replaced`** — different content (any word changed)
78
+ - **`truncated`** — current tokens are a strict prefix of captured
79
+ - **`deleted`** — the field is empty or whitespace-only on disk
80
+ - **`whitespace-only`** — token streams match but raw strings differ (**not** divergence; do not restore)
81
+ - **`none`** — byte-identical (**not** divergence)
82
+
83
+ ## Post-Restore Re-Validation (Optional)
84
+
85
+ Skills that run frontmatter compliance checks (e.g. `skf-create-skill validate.md`) should additionally re-validate the restored description against the frontmatter contract after restore — a restored value must still satisfy length limits, forbidden-token rules, and required-field shape. Run:
86
+
87
+ ```bash
88
+ uv run {project-root}/src/shared/scripts/skf-validate-frontmatter.py <skill-md-path>
89
+ ```
90
+
91
+ If the validator reports failure for the `description` field, flip the Schema row in the evidence report back to `FAIL` and record `description_guard_revalidation: FAIL` with the validator diagnostic. Do not halt — let the failure surface through the normal artifact path so step health-check and the result contract record it.
92
+
93
+ ## Why This Protocol Is Centralized
94
+
95
+ Previously, each tool invocation in each calling stage carried its own copy of the capture/verify/restore prose. Duplicated defensive logic drifts: a fix in one section did not propagate to the other, and adding a new tool invocation required remembering to copy the pattern. Centralizing the protocol gives every calling stage one place to update when external validator behavior changes.
96
+
97
+ ## Calling Workflows
98
+
99
+ - `src/skf-create-skill/references/validate.md` — wraps `skill-check check --fix` (§2) and `split-body` (§4). Runs the optional post-restore re-validation.
100
+ - `src/skf-update-skill/references/write.md` — wraps `skill-check check --fix` and `skill-check split-body --write` in §7. Does not run post-restore re-validation today; the post-write checks in §1 catch downstream issues.
@@ -42,4 +42,4 @@ There is no generic helper that writes the schema above; each skill assembles th
42
42
 
43
43
  A generalised emitter (matching this document's schema) is a reasonable future helper when a second consumer materialises with the same shape. For now, skills that write this contract assemble the JSON in their terminal step — the work is small (5–8 fields) and skill-specific summary content benefits from being expressed inline alongside the rest of the step's logic.
44
44
 
45
- skf-quick-skill writes both the success-variant contract (`step-06-finalize.md` §3) and the error-variant contract on every HARD HALT (per `SKILL.md` § "Result Contract on HARD HALT") in this hand-assembled style.
45
+ skf-quick-skill writes both the success-variant contract (`finalize.md` §3) and the error-variant contract on every HARD HALT (per `SKILL.md` § "Result Contract on HARD HALT") in this hand-assembled style.
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://github.com/armelhbobdad/bmad-module-skill-forge/src/shared/scripts/schemas/skf-brief-result-envelope.v1.json",
4
4
  "title": "SKF_BRIEF_RESULT_JSON envelope (v1)",
5
- "description": "Single-line JSON document emitted by skf-brief-skill step-05 §4b when {headless_mode} is true, prefixed with the literal 'SKF_BRIEF_RESULT_JSON: '. Pipelines grep one line out of the workflow log to branch on the brief outcome without parsing prose. Schema mirrors the contract in src/skf-brief-skill/SKILL.md Result Contract section.",
5
+ "description": "Single-line JSON document emitted by skf-brief-skill step 5 §4b when {headless_mode} is true, prefixed with the literal 'SKF_BRIEF_RESULT_JSON: '. Pipelines grep one line out of the workflow log to branch on the brief outcome without parsing prose. Schema mirrors the contract in src/skf-brief-skill/SKILL.md Result Contract section.",
6
6
  "type": "object",
7
7
  "additionalProperties": false,
8
8
  "required": ["status", "brief_path", "skill_name", "version", "language", "scope_type", "exit_code", "halt_reason"],
@@ -10,7 +10,7 @@
10
10
  "status": {
11
11
  "type": "string",
12
12
  "enum": ["success", "error"],
13
- "description": "'success' on the terminal happy path (after step-05 wrote the brief and step-06 returned). 'error' on any HARD HALT."
13
+ "description": "'success' on the terminal happy path (after step 5 wrote the brief and step 6 returned). 'error' on any HARD HALT."
14
14
  },
15
15
  "brief_path": {
16
16
  "type": ["string", "null"],
@@ -19,20 +19,20 @@
19
19
  "skill_name": {
20
20
  "type": "string",
21
21
  "minLength": 1,
22
- "description": "Brief's skill_name field — present in every envelope (success and error) since it is captured at step-01 §6 before any of the other failure branches."
22
+ "description": "Brief's skill_name field — present in every envelope (success and error) since it is captured at step 1 §6 before any of the other failure branches."
23
23
  },
24
24
  "version": {
25
25
  "type": ["string", "null"],
26
- "description": "Resolved brief version (target_version if set, else auto-detected, else '1.0.0'). Null when the run errored before step-05's version-resolution ran."
26
+ "description": "Resolved brief version (target_version if set, else auto-detected, else '1.0.0'). Null when the run errored before step 5's version-resolution ran."
27
27
  },
28
28
  "language": {
29
29
  "type": ["string", "null"],
30
- "description": "Detected or user-confirmed primary language. Null when the run errored before step-02's language-detection ran."
30
+ "description": "Detected or user-confirmed primary language. Null when the run errored before step 2's language-detection ran."
31
31
  },
32
32
  "scope_type": {
33
33
  "type": ["string", "null"],
34
34
  "enum": ["full-library", "specific-modules", "public-api", "component-library", "reference-app", "docs-only", null],
35
- "description": "Confirmed scope.type from step-03. Null when the run errored before scope was confirmed."
35
+ "description": "Confirmed scope.type from step 3. Null when the run errored before scope was confirmed."
36
36
  },
37
37
  "exit_code": {
38
38
  "type": "integer",
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://github.com/armelhbobdad/bmad-module-skill-forge/src/shared/scripts/schemas/skf-setup-result-envelope.v1.json",
4
4
  "title": "SKF_SETUP_RESULT_JSON envelope (v1)",
5
- "description": "Single-line JSON document emitted by skf-setup step-04 §4 when {headless_mode} is true, prefixed with the literal 'SKF_SETUP_RESULT_JSON: '. Pipelines grep one line out of the workflow log without parsing ASCII-art and without racing the forge-tier.yaml writer. Schema added in PR #247, extended in PR #248 (header / outputs / failure modes), extended again in this PR with previous_tier / tier_changed / tools_added / tools_removed / error.",
5
+ "description": "Single-line JSON document emitted by skf-setup step 4 §4 when {headless_mode} is true, prefixed with the literal 'SKF_SETUP_RESULT_JSON: '. Pipelines grep one line out of the workflow log without parsing ASCII-art and without racing the forge-tier.yaml writer. Schema added in PR #247, extended in PR #248 (header / outputs / failure modes), extended again in this PR with previous_tier / tier_changed / tools_added / tools_removed / error.",
6
6
  "type": "object",
7
7
  "additionalProperties": false,
8
8
  "required": ["skf_setup"],
@@ -11,6 +11,7 @@
11
11
  "type": "object",
12
12
  "additionalProperties": false,
13
13
  "required": [
14
+ "status",
14
15
  "tier",
15
16
  "previous_tier",
16
17
  "tier_changed",
@@ -27,6 +28,11 @@
27
28
  "error"
28
29
  ],
29
30
  "properties": {
31
+ "status": {
32
+ "type": "string",
33
+ "enum": ["success", "tier_failure", "write_failure", "blocked"],
34
+ "description": "Single-field outcome for pipeline branching. 'success' when no error and tier requirement (if any) is satisfied. 'tier_failure' when require_tier was set and is not satisfied. 'write_failure' when forge-tier.yaml or preferences.yaml could not be written. 'blocked' for any other halt that still produced an envelope (e.g. foreign ccc binary rejected pre-index)."
35
+ },
30
36
  "tier": {
31
37
  "type": "string",
32
38
  "enum": ["Quick", "Forge", "Forge+", "Deep"],
@@ -76,7 +82,7 @@
76
82
  "properties": {
77
83
  "status": {
78
84
  "type": "string",
79
- "enum": ["fresh", "created", "failed", "none"]
85
+ "enum": ["fresh", "created", "failed", "none", "skipped"]
80
86
  },
81
87
  "indexed_path": { "type": ["string", "null"] },
82
88
  "file_count": { "type": ["integer", "null"], "minimum": 0 }
@@ -119,7 +125,7 @@
119
125
  "phase": {
120
126
  "type": "string",
121
127
  "minLength": 1,
122
- "description": "Step or operation that failed (e.g. 'step-02-write-config:forge-tier.yaml')."
128
+ "description": "Step or operation that failed (e.g. 'write-config:forge-tier.yaml')."
123
129
  },
124
130
  "path": { "type": "string", "minLength": 1, "description": "Absolute path of the file the failed operation targeted." },
125
131
  "reason": { "type": "string", "minLength": 1, "description": "Human-readable error message." }