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
@@ -1,7 +1,12 @@
1
1
  ---
2
- nextStepFile: './step-05-detect-integrations.md'
2
+ nextStepFile: 'detect-integrations.md'
3
+ enumerateStackSkillsProbeOrder:
4
+ - '{project-root}/_bmad/skf/shared/scripts/skf-enumerate-stack-skills.py'
5
+ - '{project-root}/src/shared/scripts/skf-enumerate-stack-skills.py'
3
6
  ---
4
7
 
8
+ <!-- Config: communicate in {communication_language}. -->
9
+
5
10
  # Step 4: Parallel Library Extraction
6
11
 
7
12
  ## STEP GOAL:
@@ -16,32 +21,54 @@ For each confirmed dependency, extract key exports, usage patterns, and API surf
16
21
 
17
22
  ## MANDATORY SEQUENCE
18
23
 
19
- **CRITICAL:** Follow this sequence exactly. Do not skip, reorder, or improvise.
20
-
21
24
  ### 0. Check Compose Mode
22
25
 
23
26
  **If `compose_mode` is true:**
24
27
 
25
28
  "**Extraction data already available from individual skills. Skipping extraction phase.**"
26
29
 
27
- For each confirmed skill, load SKILL.md from the version-aware path resolved in step-02.
30
+ For each confirmed skill, load SKILL.md from the version-aware path resolved in step 2.
31
+
32
+ **Re-resolve at step 4 entry (S17):** Between step 2 manifest detection and step 4 extraction, a concurrent write could have advanced a skill's `active_version`. On entering this step, re-resolve `skill_package_path` for each confirmed skill via the export-manifest (or symlink fallback) and capture the freshly-read `version` and `metadata_hash` into workflow state. If the `metadata_hash` diverges from the value stored in step 2, log a warning `"constituent '{skill_name}' changed between step 2 and step 4 — using fresh values"` and replace the workflow-state entry (so step 7 provenance records the hash active at extraction time, with the drift logged for audit).
33
+
34
+ Use `skill_package_path` (stored in step 2 and optionally refreshed above) directly — this already points to the resolved `{skill_package}` or `{active_skill}` directory containing the skill's artifacts. If `skill_package_path` is not available, resolve via the `{active_skill}` template: `{skills_output_folder}/{skill_dir}/active/{skill_dir}/SKILL.md` (see `knowledge/version-paths.md`).
35
+
36
+ **Exports resolution order (H1) — script-driven:** Do NOT walk per-skill `metadata.json` → `references/` → SKILL.md by hand. Invoke the helper once at step entry to compute the full inventory for every confirmed skill in one deterministic call:
28
37
 
29
- **Re-resolve at step-04 entry (S17):** Between step-02 manifest detection and step-04 extraction, a concurrent write could have advanced a skill's `active_version`. On entering this step, re-resolve `skill_package_path` for each confirmed skill via the export-manifest (or symlink fallback) and capture the freshly-read `version` and `metadata_hash` into workflow state. If the `metadata_hash` diverges from the value stored in step-02, log a warning `"constituent '{skill_name}' changed between step-02 and step-04 using fresh values"` and replace the workflow-state entry (so step-07 provenance records the hash active at extraction time, with the drift logged for audit).
38
+ **Resolve `{enumerateStackSkillsHelper}`** from `{enumerateStackSkillsProbeOrder}`; first existing path wins. HALT if no candidate exists.
30
39
 
31
- Use `skill_package_path` (stored in step-02 and optionally refreshed above) directly — this already points to the resolved `{skill_package}` or `{active_skill}` directory containing the skill's artifacts. If `skill_package_path` is not available, resolve via the `{active_skill}` template: `{skills_output_folder}/{skill_dir}/active/{skill_dir}/SKILL.md` (see `knowledge/version-paths.md`).
40
+ ```bash
41
+ uv run {enumerateStackSkillsHelper} enumerate {skills_output_folder}
42
+ ```
43
+
44
+ The script emits JSON of the form:
32
45
 
33
- **Exports resolution order (H1):** For each confirmed skill, populate the `exports` field using the first source that returns a non-empty list:
46
+ ```json
47
+ {
48
+ "skills": [
49
+ {
50
+ "name": "<skill-name>",
51
+ "path": "<rel-to-skills-root, forward-slash>",
52
+ "exports": ["..."],
53
+ "exports_source": "metadata|references|skill-md|unknown",
54
+ "confidence": "T1|T2|T1-low",
55
+ "metadata_hash": "sha256:..." | null
56
+ }
57
+ ],
58
+ "cycles": ["<skill-name>"],
59
+ "warnings": ["<text>"]
60
+ }
61
+ ```
34
62
 
35
- 1. **Primary `metadata.json.exports[]`:** Read the skill's `metadata.json` and use the `exports[]` array directly. This is the most structured and trustworthy source.
36
- 2. **Fallback — `references/`:** If `metadata.json.exports[]` is empty or missing, scan the `references/` subdirectory of the skill package for per-export files and reconstruct the export list from filenames/headers. Log a warning: `"{skill_name}: metadata.json.exports[] empty — reconstructed from references/"` and record the warning in workflow state for the evidence report.
37
- 3. **Last resort — SKILL.md prose parsing:** If both prior sources are unavailable, parse the SKILL.md "Exports" / "API" section prose. Log a stronger warning: `"{skill_name}: falling back to SKILL.md prose parsing — exports may be incomplete"` and record it in workflow state.
63
+ Cache this result as `stack_skill_inventory` in workflow state — the per-skill subagent fan-out at §1+ MUST read from this cache rather than re-reading each skill's `SKILL.md` / `metadata.json` / `references/` to determine exports. Append every entry in `warnings[]` to workflow state for the evidence report (the script already labels them per-skill, e.g. `"<skill-name>: no exports found via any resolution path"`). For every entry in `cycles[]`, halt with a structured-error contract on stderr — a composes-cycle makes the stack unbuildable.
38
64
 
39
- Build a `per_library_extractions[]` entry for each skill with the following fields:
40
- - `library`: skill name from metadata.json
41
- - `exports`: exports list resolved via the order above
42
- - `exports_source`: one of `metadata|references|prose` — capture which resolution path was used (so step-07 provenance can record it)
43
- - `usage_patterns`: usage patterns from the SKILL.md usage section
44
- - `confidence`: the skill's existing confidence tier (one of `T1|T1-low|T2|T3` per `confidence-tiers.md`)inherited directly. Do not silently drop T3 evidence; carry whatever tier the source skill declared.
65
+ Build a `per_library_extractions[]` entry for each skill by reading from the cached inventory:
66
+ - `library`: `inventory.skills[i].name`
67
+ - `exports`: `inventory.skills[i].exports`
68
+ - `exports_source`: `inventory.skills[i].exports_source` (one of `metadata|references|skill-md|unknown` — capture for step 7 provenance)
69
+ - `confidence`: `inventory.skills[i].confidence` (one of `T1|T2|T1-low`; `unknown` source ⇒ `T1-low`). Do not silently drop T3 evidence; carry whatever tier the source skill declared if §1+ subagent analysis upgrades the value.
70
+ - `metadata_hash`: `inventory.skills[i].metadata_hash` — record for step 7 provenance (null when exports came from references/ or SKILL.md prose).
71
+ - `usage_patterns`: populated by the §1+ per-skill subagent fan-out, NOT by this script. The script provides the inventory + exports; the subagent does the per-skill usage analysis. They're complementary.
45
72
 
46
73
  Display an extraction summary:
47
74
 
@@ -150,7 +177,7 @@ For each library extraction:
150
177
  **If ALL extractions fail:** HALT — cannot produce meaningful stack skill. Before halting (B7):
151
178
 
152
179
  1. Purge any in-flight staging artifacts under the forge workspace: remove `{forge_data_folder}/{project_name}-stack/{version}/*-tmp` and any `{forge_data_folder}/{project_name}-stack/{version}/*.skf-tmp` directories so partial state does not linger.
153
- 2. Emit a structured error contract on stderr: `{"status":"error","skill":"skf-create-stack-skill","stage":"step-04","reason":"all extractions failed","libraries":[...]}`.
180
+ 2. Emit a structured error contract on stderr: `{"status":"error","skill":"skf-create-stack-skill","stage":"step 4","reason":"all extractions failed","libraries":[...]}`.
154
181
  3. Exit with a non-zero status so headless pipelines detect the failure.
155
182
 
156
183
  ### 4. Display Extraction Summary
@@ -1,7 +1,9 @@
1
1
  ---
2
- nextStepFile: './step-04-parallel-extract.md'
2
+ nextStepFile: 'parallel-extract.md'
3
3
  ---
4
4
 
5
+ <!-- Config: communicate in {communication_language}. -->
6
+
5
7
  # Step 3: Rank and Confirm Scope
6
8
 
7
9
  ## STEP GOAL:
@@ -15,8 +17,6 @@ Count import frequency for each dependency across the codebase, rank by usage, a
15
17
 
16
18
  ## MANDATORY SEQUENCE
17
19
 
18
- **CRITICAL:** Follow this sequence exactly. Do not skip, reorder, or improvise.
19
-
20
20
  ### 1. Count Import Frequency
21
21
 
22
22
  **If `compose_mode` is true:**
@@ -122,7 +122,7 @@ Display final confirmation:
122
122
 
123
123
  ### 5. Present MENU OPTIONS
124
124
 
125
- Display: **Select:** [C] Continue to Extraction
125
+ Display: **Select:** [C] Continue to Extraction | [X] Cancel and exit
126
126
 
127
127
  #### EXECUTION RULES:
128
128
 
@@ -133,5 +133,6 @@ Display: **Select:** [C] Continue to Extraction
133
133
  #### Menu Handling Logic:
134
134
 
135
135
  - IF C: Store current `confirmed_dependencies` (including any modifications made since initial presentation), then load, read entire file, then execute {nextStepFile}
136
+ - IF X: Invoke the rollback contract (purge any `{forge_data_folder}/{project_name}-stack/{version}/*-tmp` and `*.skf-tmp` staging artifacts under the forge workspace, leave any existing committed stack package untouched), emit the `SKF_STACK_RESULT_JSON` envelope on stderr with `status: "error"`, `halt_reason: "user-cancelled"`, `exit_code: 6`, and exit with code 6
136
137
  - IF Any other: Process as scope modification (add/remove skills from `confirmed_dependencies`), update the in-memory `confirmed_dependencies` list accordingly, redisplay the updated skills table, then [Redisplay Menu Options](#5-present-menu-options)
137
138
 
@@ -1,5 +1,5 @@
1
1
  ---
2
- nextStepFile: './step-10-health-check.md'
2
+ nextStepFile: 'health-check.md'
3
3
  # Resolve `{atomicWriteHelper}` by probing `{atomicWriteProbeOrder}` in order
4
4
  # (installed SKF module path first, src/ dev-checkout fallback); first existing
5
5
  # path wins. HALT if neither resolves.
@@ -8,6 +8,8 @@ atomicWriteProbeOrder:
8
8
  - '{project-root}/src/shared/scripts/skf-atomic-write.py'
9
9
  ---
10
10
 
11
+ <!-- Config: communicate in {communication_language}. Artifact text in {document_output_language}. -->
12
+
11
13
  # Step 9: Stack Skill Report
12
14
 
13
15
  ## STEP GOAL:
@@ -23,8 +25,6 @@ Display the final summary of the forged stack skill with confidence distribution
23
25
 
24
26
  ## MANDATORY SEQUENCE
25
27
 
26
- **CRITICAL:** Follow this sequence exactly. Do not skip, reorder, or improvise.
27
-
28
28
  ### 1. Display Stack Forged Banner
29
29
 
30
30
  "**Stack forged: {project_name}-stack — {lib_count} libraries, {integration_count} integration patterns**
@@ -1,8 +1,10 @@
1
1
  ---
2
- nextStepFile: './step-09-report.md'
2
+ nextStepFile: 'report.md'
3
3
  stackSkillTemplate: 'assets/stack-skill-template.md'
4
4
  ---
5
5
 
6
+ <!-- Config: communicate in {communication_language}. Artifact text in {document_output_language}. -->
7
+
6
8
  # Step 8: Validate Output
7
9
 
8
10
  ## STEP GOAL:
@@ -16,8 +18,6 @@ Validate all written output files against their expected structure and verify co
16
18
 
17
19
  ## MANDATORY SEQUENCE
18
20
 
19
- **CRITICAL:** Follow this sequence exactly. Do not skip, reorder, or improvise.
20
-
21
21
  ### 1. Verify File Existence
22
22
 
23
23
  Check that all expected files exist from written_files[]:
@@ -47,7 +47,7 @@ timeout 10s npx --no-install skill-check -h
47
47
  ```
48
48
 
49
49
  - If exits 0: Use skill-check for automated validation in sections 3, 9.
50
- - If exits non-zero, times out, or returns "command not found": Use manual fallback paths. Mark `metadata.validation_status: "manual-only"` (do this in step-07 when appropriate) and record every skipped check in the evidence report.
50
+ - If exits non-zero, times out, or returns "command not found": Use manual fallback paths. Mark `metadata.validation_status: "manual-only"` (do this in step 7 when appropriate) and record every skipped check in the evidence report.
51
51
 
52
52
  **Important:** Do not assume availability — empirical check required.
53
53
 
@@ -57,7 +57,7 @@ timeout 10s npx --no-install skill-check -h
57
57
 
58
58
  This validates frontmatter, description, body limits, links, formatting — and auto-fixes deterministic issues. Parse JSON for `qualityScore`, `diagnostics[]`, `fixed[]`.
59
59
 
60
- **Post-fix provenance drift guard (S15):** If `fixed[]` is non-empty, `skill-check --fix` has modified `SKILL.md` after step-07 wrote it. The safe default for v1.0 is to emit a **WARNING** finding listing each auto-fix (`"skill-check --fix modified SKILL.md: {fix_description} — metadata.json hashes/provenance may be out of date"`). Do NOT silently accept the fixes without surfacing the drift. If the caller wants authoritative metadata, they should re-run the workflow.
60
+ **Post-fix provenance drift guard (S15):** If `fixed[]` is non-empty, `skill-check --fix` has modified `SKILL.md` after step 7 wrote it. The safe default for v1.0 is to emit a **WARNING** finding listing each auto-fix (`"skill-check --fix modified SKILL.md: {fix_description} — metadata.json hashes/provenance may be out of date"`). Do NOT silently accept the fixes without surfacing the drift. If the caller wants authoritative metadata, they should re-run the workflow.
61
61
 
62
62
  **If `body.max_lines` reported**, prefer selective split: extract only the largest Tier 2 section(s) to `references/`, keeping Tier 1 content inline (inline passive context achieves 100% task accuracy vs 79% for on-demand retrieval). Fall back to `npx skill-check split-body <skill-dir> --write` if not feasible. Verify `#quick-start` and `#key-types` anchors still resolve after split. Then re-validate.
63
63
 
@@ -120,7 +120,7 @@ Verify context-snippet.md follows Vercel-aligned indexed format:
120
120
  - [ ] First line matches: `[{project}-stack v{version}]|root: {prefix}{project}-stack/` where prefix is `skills/` (draft form) or any IDE skill root (`.{dir}/skills/`)
121
121
  - [ ] Second line starts with `|IMPORTANT:`
122
122
  - [ ] Stack and integrations lines present
123
- - [ ] Approximate token count is ~80-120 tokens (use the `ceil(char_count / 4)` heuristic from step-07 §5; tolerate up to ~150 if the overflow strategy was applied and a workflow_warning was emitted)
123
+ - [ ] Approximate token count is ~80-120 tokens (use the `ceil(char_count / 4)` heuristic from step 7 §5; tolerate up to ~150 if the overflow strategy was applied and a workflow_warning was emitted)
124
124
 
125
125
  Record format violations as **WARNING** findings.
126
126
 
@@ -9,6 +9,16 @@ description: Drop a specific skill version or an entire skill — soft (deprecat
9
9
 
10
10
  Drops a specific skill version or an entire skill, either as a soft deprecation (manifest-only, files retained) or a hard purge (files deleted). Ensures platform context files are rebuilt to exclude dropped versions. Every destructive action requires explicit user confirmation — nothing is deleted silently. The export manifest is the source of truth; the filesystem is updated to match.
11
11
 
12
+ ## Conventions
13
+
14
+ - Bare paths (e.g. `references/<name>.md`) resolve from the skill root.
15
+ - `references/` holds prompt content carved out of SKILL.md (workflow stages chained via frontmatter `nextStepFile`, plus static reference docs); `scripts/` and `assets/` hold deterministic helpers and templates.
16
+ - `{skill-root}` resolves to this skill's installed directory (where `customize.toml` lives, if present).
17
+ - `{project-root}`-prefixed paths resolve from the project working directory.
18
+ - `{skill-name}` resolves to the skill directory's basename.
19
+ - **Module-level path exception:** paths starting with `knowledge/` or `shared/` resolve from the SKF module root, not the skill root — install layout puts both at `{project-root}/_bmad/skf/`. The `versionPathsKnowledge: 'knowledge/version-paths.md'` frontmatter scalar in stage files uses this convention; same for `shared/health-check.md` chained from the terminal step.
20
+ - **Cross-skill data coupling:** `references/execute.md` reads `skf-export-skill/assets/managed-section-format.md` for the IDE→context-file mapping table and the four-case (Create / Append / Regenerate / Malformed) logic when rebuilding context files. Drop-skill assumes that asset is present at install time and that its semantics are stable across the two skills' versions.
21
+
12
22
  ## Role
13
23
 
14
24
  You are Ferris in Management mode — a destructive operation specialist who enforces safety guards. You treat every drop as potentially irreversible and require explicit confirmation before touching the manifest or filesystem. You protect the active version, keep the export manifest consistent with on-disk state, and ensure downstream platform context files are rebuilt.
@@ -19,39 +29,101 @@ These rules apply to every step in this workflow:
19
29
 
20
30
  - Never delete files without explicit user confirmation in purge mode
21
31
  - Never drop an active version when other non-deprecated versions exist — enforce the active version guard
22
- - Read each step file completely before taking any action
23
- - Follow the mandatory sequence in each step exactly — do not skip, reorder, or optimize
24
32
  - Only load one step file at a time — never preload future steps
25
33
  - If any instruction references a subprocess or tool you lack, achieve the outcome in your main context thread
26
34
  - Always communicate in `{communication_language}`
35
+ - At any interactive prompt, the inputs `cancel`, `exit`, `[X]`, `q`, or `:q` exit cleanly with exit code 6 (`halt_reason: "user-cancelled"`)
27
36
  - If `{headless_mode}` is true, auto-proceed through confirmation gates with their default action and log each auto-decision
28
37
 
29
38
  ## Stages
30
39
 
31
40
  | # | Step | File | Auto-proceed |
32
41
  |---|------|------|--------------|
33
- | 1 | Select Target | steps-c/step-01-select.md | No (confirm) |
34
- | 2 | Execute Drop | steps-c/step-02-execute.md | Yes |
35
- | 3 | Report | steps-c/step-03-report.md | Yes |
36
- | 4 | Workflow Health Check | steps-c/step-04-health-check.md | Yes |
42
+ | 1 | Select Target | references/select.md | No (confirm) |
43
+ | 2 | Execute Drop | references/execute.md | Yes |
44
+ | 3 | Report | references/report.md | Yes |
45
+ | 4 | Workflow Health Check | references/health-check.md | Yes |
37
46
 
38
47
  ## Invocation Contract
39
48
 
40
49
  | Aspect | Detail |
41
50
  |--------|--------|
42
51
  | **Inputs** | skill_name [required], mode (deprecate/purge) [required], version (all/specific) [required] |
43
- | **Gates** | step-01: Input Gate [use args], Confirm Gate [Y] |
44
- | **Outputs** | Updated manifest, rebuilt context files, (purge: deleted directories) |
45
- | **Headless** | All gates auto-resolve with default action when `{headless_mode}` is true |
52
+ | **Flags** | `--headless` / `-H` (auto-resolve all gates); `--dry-run` (run selection + display the §10 confirmation block, then exit with `status="dry-run"` — no manifest mutation, no file deletion). Useful for "show me what this would touch before I commit." |
53
+ | **Gates** | step 1: Input Gate [use args], Confirm Gate [Y] |
54
+ | **Outputs** | Updated manifest, rebuilt context files, (purge: deleted directories), `drop-skill-result-{timestamp}.json` and `drop-skill-result-latest.json` |
55
+ | **Headless** | All gates auto-resolve with default action when `{headless_mode}` is true. When `forbid_purge_in_headless` is `"true"` in `customize.toml` AND `drop_mode = "purge"`, On-Activation §4 HALTs with exit code 6 (`halt_reason: "headless-purge-forbidden"`) before any work begins. |
56
+ | **Exit codes** | See "Exit Codes" below |
57
+
58
+ ## Exit Codes
59
+
60
+ Every HARD HALT in this workflow exits with a stable code so headless automators can branch on the failure class without grepping message text:
61
+
62
+ | Code | Meaning | Raised by |
63
+ | ---- | -------------------- | -------------------------------------------------------------------------------------------- |
64
+ | 0 | success | step 4 (terminal) |
65
+ | 2 | input-missing / input-invalid | step 1 §4 (headless missing `skill_name` arg) → `input-missing`; non-existent skill / unparseable version → `input-invalid` |
66
+ | 3 | resolution-failure | step 1 §2 (manifest is malformed JSON); step 1 §3 (no skills found anywhere) |
67
+ | 4 | write-failure | On-Activation §3 pre-flight write probe (skills_output_folder unwritable); step 2 §2 (manifest write); step 2 §3 (context-file rewrite); step 2 §4 (directory delete) |
68
+ | 5 | state-conflict | step 1 §7 (active-version-guard refuses to drop the active version while non-deprecated peers remain) |
69
+ | 6 | user-cancelled | step 1 §10 confirmation gate `[N]`; any prompt that accepted `cancel`/`exit`/`:q`; On-Activation §4 (`headless-purge-forbidden`) |
70
+
71
+ ## Result Contract (Headless)
72
+
73
+ When `{headless_mode}` is true, step 3 emits a single-line JSON envelope on **stdout** before chaining to step 4, and every HARD HALT emits the same envelope shape on **stderr** with `status: "error"`:
74
+
75
+ ```
76
+ SKF_DROP_SKILL_RESULT_JSON: {"status":"success|error|dry-run","skill":"…|null","drop_mode":"…|null","versions_affected":[],"files_deleted":[],"manifest_updated":false,"exit_code":0,"halt_reason":null}
77
+ ```
78
+
79
+ `status` is `"success"` on the terminal happy path, `"dry-run"` when `--dry-run` was set and the workflow exited before §11 stores decisions, `"error"` on any HALT. `halt_reason` is one of: `null` (success), `"input-missing"`, `"input-invalid"`, `"manifest-corrupt"`, `"nothing-to-drop"`, `"active-version-guard-refused"`, `"headless-purge-forbidden"`, `"manifest-write-failed"`, `"context-rebuild-failed"`, `"delete-failed"`, `"write-failed"`, `"user-cancelled"`. `exit_code` matches the table above.
46
80
 
47
81
  ## On Activation
48
82
 
49
83
  1. Load config from `{project-root}/_bmad/skf/config.yaml` and resolve:
50
84
  - `project_name`, `output_folder`, `user_name`, `communication_language`, `document_output_language`
51
85
  - `skills_output_folder`, `forge_data_folder`, `sidecar_path`
52
- - `snippet_skill_root_override` (optional string) — when set, the context-file rebuild in step-02 preserves any snippet `root:` prefix that matches the override instead of rewriting it to the target IDE's skill root. See `skf-export-skill/assets/managed-section-format.md` for full semantics.
86
+ - `snippet_skill_root_override` (optional string) — when set, the context-file rebuild in step 2 preserves any snippet `root:` prefix that matches the override instead of rewriting it to the target IDE's skill root. See `skf-export-skill/assets/managed-section-format.md` for full semantics.
53
87
  - Generate and store `timestamp` as `YYYYMMDD-HHmmss` format. This value is fixed for the entire workflow run.
54
88
 
55
- 2. **Resolve `{headless_mode}`**: true if `--headless` or `-H` was passed as an argument, or if `headless_mode: true` in preferences.yaml. Default: false.
89
+ 2. **Resolve `{headless_mode}`**: true if `--headless` or `-H` was passed as an argument, or if `headless_mode: true` in `{sidecar_path}/preferences.yaml`. Default: false.
90
+
91
+ 3. **Resolve workflow customization.** Run:
92
+
93
+ ```bash
94
+ python3 {project-root}/_bmad/scripts/resolve_customization.py \
95
+ --skill {skill-root} --key workflow
96
+ ```
97
+
98
+ The script merges the three customization layers per `bmad-customize`'s structural merge rules (scalars override, arrays append):
99
+
100
+ - `{skill-root}/customize.toml` — bundled defaults
101
+ - `_bmad/custom/<skill-name>.toml` under `{project-root}` — team overrides (committed)
102
+ - `_bmad/custom/<skill-name>.user.toml` under `{project-root}` — personal overrides (gitignored)
103
+
104
+ If the script fails or is missing, fall back to reading `{skill-root}/customize.toml` directly — the bundled defaults are an empty string for each scalar.
105
+
106
+ Apply the scalar fallback now so stage files don't have to repeat the conditional logic. For each of the four scalars, if the merged value is empty or absent, the bundled default applies:
107
+
108
+ - `{defaultMode}` ← `workflow.default_mode` (empty = always prompt; `"deprecate"` or `"purge"` = skip §8 Ask Mode)
109
+ - `{forbidPurgeInHeadless}` ← `workflow.forbid_purge_in_headless` (empty or non-`"true"` = no guard)
110
+ - `{unknownIdeDefaultContextFile}` ← `workflow.unknown_ide_default_context_file` if non-empty, else `AGENTS.md`
111
+ - `{unknownIdeDefaultSkillRoot}` ← `workflow.unknown_ide_default_skill_root` if non-empty, else `.agents/skills/`
112
+
113
+ Stash all four as workflow-context variables. Stage files reference them directly — no conditional at the usage site.
114
+
115
+ 4. **Pre-flight write probe + headless-purge guard.**
116
+
117
+ First, verify `{skills_output_folder}` is writable. A read-only mount, full disk, or permissions-denied path otherwise only surfaces at step 2's manifest write — by then the user has already gone through every selection prompt:
118
+
119
+ ```bash
120
+ mkdir -p "{skills_output_folder}" && \
121
+ printf 'probe' > "{skills_output_folder}/.skf-write-probe" && \
122
+ rm "{skills_output_folder}/.skf-write-probe"
123
+ ```
124
+
125
+ On any non-zero exit: HALT (exit code 4, `halt_reason: "write-failed"`). In headless mode, emit the error envelope per **Result Contract (Headless)** with `skill: null` and `drop_mode: null` (neither is resolved yet at activation time).
126
+
127
+ Second, enforce the headless-purge guard. If `{headless_mode}` is true AND `{forbidPurgeInHeadless}` is `"true"` AND the parsed `mode` arg is `"purge"`: HALT with exit code 6 and `halt_reason: "headless-purge-forbidden"`, emit the error envelope, and exit immediately. The operator must re-run with `mode=deprecate` or set `forbid_purge_in_headless = ""` (or omit the override entirely) to proceed.
56
128
 
57
- 3. Load, read the full file, and then execute `./steps-c/step-01-select.md` to begin the workflow.
129
+ 5. Load, read the full file, and then execute `references/select.md` to begin the workflow.
@@ -0,0 +1,57 @@
1
+ # DO NOT EDIT -- overwritten on every update.
2
+ #
3
+ # Workflow customization surface for skf-drop-skill.
4
+
5
+ [workflow]
6
+
7
+ # --- Configurable below. Overrides merge per BMad structural rules: ---
8
+ # scalars: override wins • arrays (persistent_facts, activation_steps_*): append
9
+ # arrays-of-tables with `code`/`id`: replace matching items, append new ones.
10
+
11
+ # Steps to run before the standard activation (uv probe, config load).
12
+ # Overrides append. Use for org-wide pre-flight checks (audit-log emit,
13
+ # ticket-reference enforcement) that must precede any destructive work.
14
+
15
+ activation_steps_prepend = []
16
+
17
+ # Steps to run after activation but before the first stage executes.
18
+ # Overrides append. Use for context loads or banner customization that
19
+ # should run once activation completes successfully.
20
+
21
+ activation_steps_append = []
22
+
23
+ # Persistent facts the workflow keeps in mind for the whole run
24
+ # (drop-policy reminders, retention guardrails, audit-trail rules).
25
+ # Overrides append.
26
+ #
27
+ # Each entry is either:
28
+ # - a literal sentence, e.g. "Purges of skills tagged `compliance` require ticket reference."
29
+ # - a file reference prefixed with `file:`, e.g.
30
+ # "file:{project-root}/docs/drop-policy.md" (globs supported; file
31
+ # contents are loaded and treated as facts).
32
+
33
+ persistent_facts = [
34
+ "file:{project-root}/**/project-context.md",
35
+ ]
36
+
37
+ # --- Optional safety + default scalars ---
38
+ #
39
+ # Default drop mode. Empty string = always prompt the user at §8 Ask Mode.
40
+ # Set to "deprecate" or "purge" to skip the prompt — the headless
41
+ # auto-decision log records the override source.
42
+
43
+ default_mode = ""
44
+
45
+ # Hard-block hard-purge in headless mode. When set to "true", a headless
46
+ # invocation with `mode=purge` HALTs at activation with exit code 6
47
+ # (`halt_reason: "headless-purge-forbidden"`) instead of silently deleting
48
+ # files. Operators must either re-run with `mode=deprecate` or unset this
49
+ # flag for that run. Empty string = no guard (default).
50
+
51
+ forbid_purge_in_headless = ""
52
+
53
+ # Fallback IDE → context-file mapping for unknown IDEs in `config.yaml.ides`.
54
+ # Empty string = use bundled defaults (AGENTS.md / .agents/skills/).
55
+
56
+ unknown_ide_default_context_file = ""
57
+ unknown_ide_default_skill_root = ""
@@ -1,26 +1,42 @@
1
1
  ---
2
- nextStepFile: './step-03-report.md'
2
+ nextStepFile: 'report.md'
3
3
  versionPathsKnowledge: 'knowledge/version-paths.md'
4
4
  managedSectionLogic: 'skf-export-skill/assets/managed-section-format.md'
5
+ # Resolve `{manifestOpsHelper}` by probing `{manifestOpsProbeOrder}` in
6
+ # order (installed SKF module path first, src/ dev-checkout fallback);
7
+ # first existing path wins. §2 calls it for atomic manifest deprecate /
8
+ # remove with v1→v2 migration handled internally — letting the LLM hand-
9
+ # roll JSON manipulation risks key-order drift, indent regressions, and
10
+ # write-atomicity bugs. HALT if neither candidate exists.
11
+ manifestOpsProbeOrder:
12
+ - '{project-root}/_bmad/skf/shared/scripts/skf-manifest-ops.py'
13
+ - '{project-root}/src/shared/scripts/skf-manifest-ops.py'
14
+ # Resolve `{rebuildManagedSectionsHelper}` similarly. §3 calls it (replace
15
+ # action) for the surgical between-marker rewrite — the LLM still computes
16
+ # the new managed section text, but the file mutation is deterministic
17
+ # (atomic temp-file + rename, marker preservation, post-write verify).
18
+ rebuildManagedSectionsProbeOrder:
19
+ - '{project-root}/_bmad/skf/shared/scripts/skf-rebuild-managed-sections.py'
20
+ - '{project-root}/src/shared/scripts/skf-rebuild-managed-sections.py'
5
21
  ---
6
22
 
23
+ <!-- Config: communicate in {communication_language}. -->
24
+
7
25
  # Step 2: Execute Drop
8
26
 
9
27
  ## STEP GOAL:
10
28
 
11
- Execute the drop decisions recorded in step-01: update the export manifest, rebuild platform context files so dropped versions disappear from managed sections, and (in purge mode) delete the affected directories from disk. Record everything that was changed for the final report in step-03.
29
+ Execute the drop decisions recorded in step 1: update the export manifest, rebuild platform context files so dropped versions disappear from managed sections, and (in purge mode) delete the affected directories from disk. Record everything that was changed for the final report in step 3.
12
30
 
13
31
  ## Rules
14
32
 
15
33
  - Focus only on manifest update, context rebuild, and (in purge mode) file deletion
16
- - Do not re-prompt the user — decisions were made in step-01
34
+ - Do not re-prompt the user — decisions were made in step 1
17
35
  - Do not delete files in deprecate mode; do not widen deletion scope beyond `affected_directories`
18
36
  - Report each stage's outcome as it completes
19
37
 
20
38
  ## MANDATORY SEQUENCE
21
39
 
22
- **CRITICAL:** Follow this sequence exactly. Do not skip, reorder, or improvise unless user explicitly requests a change.
23
-
24
40
  ### 1. Re-read Version-Paths Knowledge
25
41
 
26
42
  Read `{versionPathsKnowledge}` again and confirm the templates and management operations. This ensures the execution step uses the same rules as the selection step even when run in isolation.
@@ -33,32 +49,33 @@ Also read `{managedSectionLogic}` for the format template, the four-case logic,
33
49
 
34
50
  **If `target_in_manifest == true`:**
35
51
 
36
- Load `{skills_output_folder}/.export-manifest.json`.
52
+ **Resolve `{manifestOpsHelper}`** from `{manifestOpsProbeOrder}`; first existing path wins. HALT (exit code 4, `halt_reason: "manifest-write-failed"`) if no candidate exists — atomic manifest mutation must go through the helper.
37
53
 
38
54
  **If `is_skill_level == false` (version-level drop):**
39
55
 
40
- For each version in `target_versions`:
56
+ For each version in `target_versions`, invoke:
41
57
 
42
- 1. Navigate to `exports.{target_skill}.versions.{version}`
43
- 2. Set `status = "deprecated"`
44
- 3. Leave `ides`, `last_exported`, and all other fields unchanged
58
+ ```bash
59
+ python3 {manifestOpsHelper} {skills_output_folder} deprecate {target_skill} {version}
60
+ ```
45
61
 
46
- Do NOT change `active_version` on the skill entry in this pass — if the dropped version was the active one (only reachable when it was the sole non-deprecated version per the step-01 guard), the active_version field will still point at it, but every consumer excludes deprecated versions from exports.
62
+ The helper sets `exports.{target_skill}.versions.{version}.status = "deprecated"` and writes the manifest atomically. It does NOT change `active_version` on the skill entry — if the dropped version was the active one (only reachable when it was the sole non-deprecated version per the step 1 guard), the field still points at it, but every consumer excludes deprecated versions from exports.
47
63
 
48
64
  **If `is_skill_level == true` (skill-level drop):**
49
65
 
50
- 1. Delete the `exports.{target_skill}` key entirely from the manifest
51
- 2. Leave all other skill entries untouched
66
+ ```bash
67
+ python3 {manifestOpsHelper} {skills_output_folder} remove {target_skill}
68
+ ```
52
69
 
53
- **Write the updated manifest back to `{skills_output_folder}/.export-manifest.json`.**
70
+ The helper deletes the `exports.{target_skill}` key entirely; other entries are untouched.
54
71
 
55
72
  Set context flag `manifest_updated = true`.
56
73
 
57
- **On error (read/parse/write failure):**
74
+ **On error (helper non-zero exit):**
58
75
 
59
76
  - Do not proceed to section 3
60
- - Report: "**Manifest update failed:** {error}. No files were deleted and platform context files were not rebuilt. The manifest is in its pre-drop state — rerun the workflow once the underlying issue is resolved."
61
- - Store `manifest_updated = false` and jump to section 6
77
+ - Report: "**Manifest update failed:** {captured stderr}. No files were deleted and platform context files were not rebuilt. The manifest is in its pre-drop state — rerun the workflow once the underlying issue is resolved."
78
+ - Store `manifest_updated = false` and jump to section 6. In headless mode, emit the error envelope per SKILL.md "Result Contract (Headless)" with `halt_reason: "manifest-write-failed"` and exit code 4.
62
79
 
63
80
  ### 3. Rebuild Context Files
64
81
 
@@ -82,20 +99,20 @@ For each entry in `target_context_files`:
82
99
  - If the file exists but contains no `<!-- SKF:BEGIN -->` marker, skip this context file (no managed section to rewrite)
83
100
  - If the file contains `<!-- SKF:BEGIN -->` but no matching `<!-- SKF:END -->`, record the error against that context file and continue to the next entry — do not halt the entire drop on a malformed context file. The manifest has already been updated in section 2 and is canonical state; the context file can be repaired manually and rebuilt on the next `[EX] Export Skill` run.
84
101
 
85
- 3. **Build the exported skill set (version-aware, deprecated-excluded)** using the same logic as export-skill step-04 section 4b:
102
+ 3. **Build the exported skill set (version-aware, deprecated-excluded)** using the same logic as export-skill step 4 section 4b:
86
103
  - Read the manifest's `exports` object (already updated in section 2)
87
104
  - For each skill, resolve its `active_version`
88
105
  - If `versions.{active_version}.status == "deprecated"`, skip that skill entirely
89
106
  - The result is the set of `{skill-name, active_version}` pairs that should appear in the managed section
90
107
 
91
- 4. **Resolve and filter snippets** using export-skill step-04 section 4c logic:
108
+ 4. **Resolve and filter snippets** using export-skill step 4 section 4c logic:
92
109
  - For each `{skill-name, active_version}` in the set, read `{skills_output_folder}/{skill-name}/{active_version}/{skill-name}/context-snippet.md`
93
110
  - If the file is missing, fall back to the `active` symlink path, then skip with a warning if still not found
94
111
  - Collect successful snippets into the skill index
95
112
 
96
- 5. **Rewrite root paths for the current context file** using the generic rewrite algorithm from export-skill step-04 section 4d:
113
+ 5. **Rewrite root paths for the current context file** using the generic rewrite algorithm from export-skill step 4 section 4d:
97
114
 
98
- For each snippet, parse the `root:` line (`root: {prefix}{skill-name}/`), strip the trailing `{skill-name}/` to extract the current prefix, and replace it with the **effective target prefix** if different. The effective target prefix is `snippet_skill_root_override` when that key is set in config.yaml — applied uniformly to every snippet so the managed section references the real on-disk location and never mixes override and per-IDE paths — otherwise the current entry's `skill_root`. See `skf-export-skill/steps-c/step-04-update-context.md` §4d for full semantics.
115
+ For each snippet, parse the `root:` line (`root: {prefix}{skill-name}/`), strip the trailing `{skill-name}/` to extract the current prefix, and replace it with the **effective target prefix** if different. The effective target prefix is `snippet_skill_root_override` when that key is set in config.yaml — applied uniformly to every snippet so the managed section references the real on-disk location and never mixes override and per-IDE paths — otherwise the current entry's `skill_root`. See `skf-export-skill/references/update-context.md` §4d for full semantics.
99
116
 
100
117
  6. **Sort skills alphabetically by name.** Count totals (skills, stack skills).
101
118
 
@@ -117,17 +134,15 @@ For each entry in `target_context_files`:
117
134
 
118
135
  If the filtered skill index is empty (e.g., the dropped skill was the only one), still emit the header with `0 skills|0 stack` and no skill entries. This keeps the managed section syntactically valid.
119
136
 
120
- 8. **Surgical replacement — Case 3 (Regenerate) only:**
121
- - Locate the `<!-- SKF:BEGIN` line — preserve everything before it
122
- - Locate the `<!-- SKF:END -->` line — preserve everything after it
123
- - Replace everything between the markers (inclusive) with the new managed section
124
- - Write the file back
137
+ 8. **Surgical replacement — atomic, deterministic.** Resolve `{rebuildManagedSectionsHelper}` from `{rebuildManagedSectionsProbeOrder}`; first existing path wins. Then invoke:
138
+
139
+ ```bash
140
+ python3 {rebuildManagedSectionsHelper} {context_file} replace --content "{new_managed_section_text}"
141
+ ```
142
+
143
+ The helper handles marker location, between-marker swap, atomic temp-file + rename, and post-write verification (markers preserved, content outside markers byte-identical). It exits non-zero on any failure with a clear `stderr` reason.
125
144
 
126
- 9. **Verify:**
127
- - Re-read the written file
128
- - Confirm both markers are present
129
- - Confirm `{target_skill}` (at the dropped version, or at all versions if skill-level) no longer appears between the markers
130
- - Confirm content outside the markers is byte-identical to what was preserved
145
+ 9. **Verify (deferred to helper).** The `replace` action above performs verification internally. Treat any non-zero exit code as a per-file failure (next bullet). If the helper is missing entirely (no probe candidate exists), HALT (exit code 4, `halt_reason: "context-rebuild-failed"`) — the rewrite cannot proceed without the atomic helper.
131
146
 
132
147
  10. **On per-file failure:** record the error against that context file and continue to the next entry. Do not halt — other context files should still be rebuilt.
133
148
 
@@ -155,7 +170,7 @@ Report: "**Rebuilt managed sections in:** {list of updated files}. {if any faile
155
170
  - `{skills_output_folder}/{target_skill}/{version}/` is deleted, but `{skills_output_folder}/{target_skill}/` remains (it still contains other versions or the `active` symlink)
156
171
  - If the `active` symlink pointed to the just-deleted version, update or remove it:
157
172
  - If other versions remain in the manifest for `{target_skill}`, repoint `active` to the manifest's current `active_version` (skipping deprecated)
158
- - If no non-deprecated versions remain, remove the `active` symlink (reachable only when dropping the sole surviving version, which in step-01 was permitted because no other non-deprecated versions existed)
173
+ - If no non-deprecated versions remain, remove the `active` symlink (reachable only when dropping the sole surviving version, which in step 1 was permitted because no other non-deprecated versions existed)
159
174
 
160
175
  4. **Skill-level purge:**
161
176
  - `{skills_output_folder}/{target_skill}/` and `{forge_data_folder}/{target_skill}/` are deleted in full — the `active` symlink disappears with the parent directory
@@ -180,11 +195,11 @@ Run these verification checks:
180
195
 
181
196
  3. **Purge check (purge mode only):** For each path in `files_deleted`, confirm it no longer exists on disk.
182
197
 
183
- If any verification fails, record the specific failure in `verification_errors` but do not halt — proceed to step-03 so the report can surface what succeeded and what needs manual attention.
198
+ If any verification fails, record the specific failure in `verification_errors` but do not halt — proceed to step 3 so the report can surface what succeeded and what needs manual attention.
184
199
 
185
200
  ### 6. Store Results in Context
186
201
 
187
- Store the following for step-03:
202
+ Store the following for step 3:
188
203
 
189
204
  - `files_deleted` — list of directory paths actually deleted (purge mode) or `[]` (soft drop)
190
205
  - `disk_freed` — human-readable size (purge mode) or `"N/A (soft drop)"`
@@ -1,10 +1,12 @@
1
1
  ---
2
- # `shared/health-check.md` resolves relative to the SKF module root
3
- # (`_bmad/skf/` when installed, `src/` during development), NOT relative
4
- # to this step file.
2
+ # Note: `shared/health-check.md` resolves relative to the SKF module root
3
+ # ({project-root}/_bmad/skf/ when installed, {project-root}/src/ during
4
+ # development), NOT relative to this step file.
5
5
  nextStepFile: 'shared/health-check.md'
6
6
  ---
7
7
 
8
+ <!-- Config: communicate in {communication_language}. -->
9
+
8
10
  # Step 4: Workflow Health Check
9
11
 
10
12
  ## STEP GOAL:
@@ -13,7 +15,7 @@ Chain to the shared workflow self-improvement health check at `{nextStepFile}`.
13
15
 
14
16
  ## Rules
15
17
 
16
- - No user-facing reports, file writes, or result contracts in this step — those belong in step-03
18
+ - No user-facing reports, file writes, or result contracts in this step — those belong in step 3
17
19
  - Delegate directly to `{nextStepFile}` with no additional commentary
18
20
  - Do not attempt any other action between loading this step and executing `{nextStepFile}`
19
21