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,8 +1,13 @@
1
1
  ---
2
- outputFile: '{output_folder}/refined-architecture-{project_name}.md'
3
- nextStepFile: './step-07-health-check.md'
2
+ # {outputFile} resolves from the activation-stored {outputFolderPath}
3
+ # variable (set in SKILL.md On Activation §4 from output_folder config +
4
+ # customize override).
5
+ outputFile: '{outputFolderPath}/refined-architecture-{project_name}.md'
6
+ nextStepFile: 'health-check.md'
4
7
  ---
5
8
 
9
+ <!-- Config: communicate in {communication_language}. Render the user-facing summary in {document_output_language}. -->
10
+
6
11
  # Step 6: Present Report
7
12
 
8
13
  ## STEP GOAL:
@@ -17,8 +22,6 @@ Present the complete refinement summary to the user. Display counts of gaps fill
17
22
 
18
23
  ## MANDATORY SEQUENCE
19
24
 
20
- **CRITICAL:** Follow this sequence exactly. Do not skip, reorder, or improvise.
21
-
22
25
  ### 1. Load Refined Document
23
26
 
24
27
  Read the `{outputFile}` to have all data available for presentation.
@@ -81,7 +84,13 @@ Re-run **[RA] Refine Architecture** anytime after updating your skills or archit
81
84
 
82
85
  ### Result Contract
83
86
 
84
- Write the result contract per `shared/references/output-contract-schema.md`: the per-run record at `{output_folder}/refine-architecture-result-{YYYYMMDD-HHmmss}.json` (UTC timestamp, resolution to seconds) and a copy at `{output_folder}/refine-architecture-result-latest.json` (stable path for pipeline consumers — copy, not symlink). Include the refined architecture doc path in `outputs`; include `gap_count`, `issue_count`, and `improvement_count` in `summary`.
87
+ Write the result contract per `shared/references/output-contract-schema.md`: the per-run record at `{outputFolderPath}/refine-architecture-result-{timestamp}.json` (reuse the activation-stored `{timestamp}`, resolution to seconds) and a copy at `{outputFolderPath}/refine-architecture-result-latest.json` (stable path for pipeline consumers — copy, not symlink). Include the refined architecture doc path in `outputs`; include `gap_count`, `issue_count`, and `improvement_count` in `summary`. On any write failure: HALT (exit code 4, `halt_reason: "write-failed"`) and emit the error envelope.
88
+
89
+ When `{headless_mode}` is true, also emit the single-line envelope on **stdout** before chaining to step 7 (matches the SKILL.md "Result Contract (Headless)" shape):
90
+
91
+ ```
92
+ SKF_REFINE_ARCHITECTURE_RESULT_JSON: {"status":"success","refined_path":"{outputFile}","gap_count":{gap_count},"issue_count":{issue_count},"improvement_count":{improvement_count},"exit_code":0,"halt_reason":null}
93
+ ```
85
94
 
86
95
  Then load, read the full file, and execute `{nextStepFile}` — the health-check step is the true terminal step of this workflow.
87
96
 
@@ -9,6 +9,16 @@ description: Rename a skill across all its versions — transactional copy-verif
9
9
 
10
10
  Renames a skill across all its versions with transactional safety — copy to the new name, verify all references updated, delete the old name only after verification succeeds. Rebuilds platform context files to reference the new name. The agentskills.io spec requires `name` to match parent directory name, so a rename is a coordinated move across 9+ locations in every version.
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 skill-index rebuild rules when re-keying context files post-rename. Rename-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 precision surgeon who operates on the entire skill group atomically. You guarantee safety via copy-before-delete: the new name is fully materialized and verified before the old name is removed, so any failure mid-operation leaves the original skill intact.
@@ -20,39 +30,99 @@ These rules apply to every step in this workflow:
20
30
  - Never delete the old skill directories until the new name has been fully materialized and verified
21
31
  - Never proceed past a verification failure — roll back (delete new directories) and halt
22
32
  - Never allow a rename to collide with an existing skill name
23
- - Read each step file completely before taking any action
24
- - Follow the mandatory sequence in each step exactly — do not skip, reorder, or optimize
25
33
  - Only load one step file at a time — never preload future steps
26
34
  - If any instruction references a subprocess or tool you lack, achieve the outcome in your main context thread
27
35
  - Always communicate in `{communication_language}`
36
+ - At any interactive prompt, the inputs `cancel`, `exit`, `[X]`, `q`, or `:q` exit cleanly with exit code 6 (`halt_reason: "user-cancelled"`)
28
37
  - If `{headless_mode}` is true, auto-proceed through confirmation gates with their default action and log each auto-decision
29
38
 
30
39
  ## Stages
31
40
 
32
41
  | # | Step | File | Auto-proceed |
33
42
  |---|------|------|--------------|
34
- | 1 | Select & Validate | steps-c/step-01-select.md | No (confirm) |
35
- | 2 | Execute Rename | steps-c/step-02-execute.md | No (confirm) |
36
- | 3 | Report | steps-c/step-03-report.md | Yes |
37
- | 4 | Workflow Health Check | steps-c/step-04-health-check.md | Yes |
43
+ | 1 | Select & Validate | references/select.md | No (confirm) |
44
+ | 2 | Execute Rename | references/execute.md | No (confirm) |
45
+ | 3 | Report | references/report.md | Yes |
46
+ | 4 | Workflow Health Check | references/health-check.md | Yes |
38
47
 
39
48
  ## Invocation Contract
40
49
 
41
50
  | Aspect | Detail |
42
51
  |--------|--------|
43
52
  | **Inputs** | old_name [required], new_name [required] |
44
- | **Gates** | step-01: Input Gate [use args] x2, Confirm Gate [Y] |
45
- | **Outputs** | Renamed skill directories, updated manifest, updated context files |
46
- | **Headless** | All gates auto-resolve with default action when `{headless_mode}` is true |
53
+ | **Flags** | `--headless` / `-H` (auto-resolve all gates); `--dry-run` (run selection + validation + display the §8 confirmation block, then exit with `status="dry-run"` — no copy, no manifest re-key, no delete). Useful for verifying the rename plan before the irreversible §8 (delete old) section. |
54
+ | **Gates** | step 1: Input Gate [use args] x2, Confirm Gate [Y] |
55
+ | **Outputs** | Renamed skill directories, updated manifest, updated context files, `{new_name}/rename-skill-result-{timestamp}.json` and `{new_name}/rename-skill-result-latest.json` |
56
+ | **Concurrency** | Two simultaneous rename runs against the same `old_name` would corrupt state mid-copy. select.md §4b acquires a PID-file lock at `{forge_data_folder}/{old_name}/.skf-rename.lock` once `old_name` is resolved; live-PID collisions HALT with `halt_reason: "halted-for-concurrent-run"`. Stale locks (dead PID) are cleared silently with a warning. The lock is released by the terminal health-check step (step 4) and by every documented halt path. |
57
+ | **Headless** | All gates auto-resolve with default action when `{headless_mode}` is true. The §6 source-authority warning HALTs by default in headless when `source_authority="official"`; set `force_source_authority_in_headless = "true"` in `customize.toml` to auto-acknowledge and proceed (the override is recorded in `headless_decisions[]`). |
58
+ | **Exit codes** | See "Exit Codes" below |
59
+
60
+ ## Exit Codes
61
+
62
+ Every HARD HALT in this workflow exits with a stable code so headless automators can branch on the failure class without grepping message text:
63
+
64
+ | Code | Meaning | Raised by |
65
+ | ---- | -------------------- | -------------------------------------------------------------------------------------------- |
66
+ | 0 | success | step 4 (terminal) |
67
+ | 2 | input-missing / input-invalid | step 1 §4/§5 (headless missing `old_name`/`new_name` arg) → `input-missing`; new name fails kebab-case / length / same-as-old → `input-invalid` |
68
+ | 3 | resolution-failure | step 1 §2 (manifest is malformed JSON); step 1 §3 (no skills found anywhere) |
69
+ | 4 | write-failure | On-Activation §3 pre-flight write probe (skills_output_folder / forge_data_folder unwritable); step 2 §1 (copy); step 2 §3 (file content update); step 2 §6 (manifest write); step 2 §7 (context-file rewrite) |
70
+ | 5 | state-conflict | step 1 §5 (name-collision check fails: target name already in use); step 1 §6 (source-authority="official" headless without `force_source_authority_in_headless`); concurrency lock collision (`halted-for-concurrent-run`) |
71
+ | 6 | user-cancelled | step 1 §6 (source-authority warning [N]); step 1 §8 confirmation gate `[N]`; any prompt that accepted `cancel`/`exit`/`:q` |
72
+
73
+ ## Result Contract (Headless)
74
+
75
+ 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"`:
76
+
77
+ ```
78
+ SKF_RENAME_SKILL_RESULT_JSON: {"status":"success|error|dry-run","old_name":"…|null","new_name":"…|null","versions_renamed":[],"manifest_rekeyed":false,"context_files_updated":[],"exit_code":0,"halt_reason":null}
79
+ ```
80
+
81
+ `status` is `"success"` on the terminal happy path, `"dry-run"` when `--dry-run` was set and the workflow exited before §9 stores decisions, `"error"` on any HALT. `halt_reason` is one of: `null` (success), `"input-missing"`, `"input-invalid"`, `"manifest-corrupt"`, `"nothing-to-rename"`, `"name-collision"`, `"source-authority-blocked"`, `"halted-for-concurrent-run"`, `"copy-failed"`, `"verify-failed"`, `"manifest-write-failed"`, `"context-rebuild-failed"`, `"write-failed"`, `"user-cancelled"`. `exit_code` matches the table above.
47
82
 
48
83
  ## On Activation
49
84
 
50
85
  1. Load config from `{project-root}/_bmad/skf/config.yaml` and resolve:
51
86
  - `project_name`, `output_folder`, `user_name`, `communication_language`, `document_output_language`
52
87
  - `skills_output_folder`, `forge_data_folder`, `sidecar_path`
53
- - `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.
88
+ - `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.
54
89
  - Generate and store `timestamp` as `YYYYMMDD-HHmmss` format. This value is fixed for the entire workflow run.
55
90
 
56
- 2. **Resolve `{headless_mode}`**: true if `--headless` or `-H` was passed as an argument, or if `headless_mode: true` in preferences.yaml. Default: false.
91
+ 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.
92
+
93
+ 3. **Resolve workflow customization.** Run:
94
+
95
+ ```bash
96
+ python3 {project-root}/_bmad/scripts/resolve_customization.py \
97
+ --skill {skill-root} --key workflow
98
+ ```
99
+
100
+ The script merges the three customization layers per `bmad-customize`'s structural merge rules (scalars override, arrays append):
101
+
102
+ - `{skill-root}/customize.toml` — bundled defaults
103
+ - `_bmad/custom/<skill-name>.toml` under `{project-root}` — team overrides (committed)
104
+ - `_bmad/custom/<skill-name>.user.toml` under `{project-root}` — personal overrides (gitignored)
105
+
106
+ 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.
107
+
108
+ Apply the scalar fallback now so stage files don't have to repeat the conditional logic. For each of the three scalars, if the merged value is empty or absent, the bundled default applies:
109
+
110
+ - `{forceSourceAuthorityInHeadless}` ← `workflow.force_source_authority_in_headless` (empty or non-`"true"` = HALT in headless on `"official"` source-authority)
111
+ - `{unknownIdeDefaultContextFile}` ← `workflow.unknown_ide_default_context_file` if non-empty, else `AGENTS.md`
112
+ - `{unknownIdeDefaultSkillRoot}` ← `workflow.unknown_ide_default_skill_root` if non-empty, else `.agents/skills/`
113
+
114
+ Stash all three as workflow-context variables. Stage files reference them directly — no conditional at the usage site.
115
+
116
+ 4. **Pre-flight write probe.** Verify both `{skills_output_folder}` and `{forge_data_folder}` are writable. A read-only mount, full disk, or permissions-denied path otherwise only surfaces inside step 2's transactional copy — by then the user has already gone through name validation and confirmation:
117
+
118
+ ```bash
119
+ for dir in "{skills_output_folder}" "{forge_data_folder}"; do
120
+ mkdir -p "$dir" && \
121
+ printf 'probe' > "$dir/.skf-write-probe" && \
122
+ rm "$dir/.skf-write-probe"
123
+ done
124
+ ```
125
+
126
+ 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 `old_name: null` and `new_name: null` (neither is resolved yet at activation time).
57
127
 
58
- 3. Load, read the full file, and then execute `./steps-c/step-01-select.md` to begin the workflow.
128
+ 5. Load, read the full file, and then execute `references/select.md` to begin the workflow.
@@ -0,0 +1,52 @@
1
+ # DO NOT EDIT -- overwritten on every update.
2
+ #
3
+ # Workflow customization surface for skf-rename-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 rename 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
+ # (rename-policy reminders, public-name-stability rules, audit guardrails).
25
+ # Overrides append.
26
+ #
27
+ # Each entry is either:
28
+ # - a literal sentence, e.g. "Renames of skills tagged `published` require approval."
29
+ # - a file reference prefixed with `file:`, e.g.
30
+ # "file:{project-root}/docs/rename-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
+ # Auto-acknowledge the source-authority="official" warning in headless mode.
40
+ # Empty string = HALT in headless when source_authority is "official"
41
+ # (the safe default — local renames diverge from any registry-published
42
+ # name). Set to "true" to silently proceed and record the override in the
43
+ # headless decision trail.
44
+
45
+ force_source_authority_in_headless = ""
46
+
47
+ # Fallback IDE → context-file mapping for unknown IDEs in `config.yaml.ides`.
48
+ # Empty string = use bundled defaults (AGENTS.md / .agents/skills/).
49
+ # Used by execute.md §7 when rebuilding context files.
50
+
51
+ unknown_ide_default_context_file = ""
52
+ unknown_ide_default_skill_root = ""
@@ -1,19 +1,48 @@
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 `{atomicWriteHelper}` by probing `{atomicWriteProbeOrder}` in
6
+ # order (installed SKF module path first, src/ dev-checkout fallback);
7
+ # first existing path wins. §3 + §6 use it for crash-safe file rewrites
8
+ # (stage to .skf-tmp, fsync, rename) — letting the LLM write directly
9
+ # risks half-written artifacts on process kill or disk-full mid-write.
10
+ # HALT if neither candidate exists.
11
+ atomicWriteProbeOrder:
12
+ - '{project-root}/_bmad/skf/shared/scripts/skf-atomic-write.py'
13
+ - '{project-root}/src/shared/scripts/skf-atomic-write.py'
14
+ # Resolve `{updateActiveSymlinkHelper}` similarly. §4 uses it to
15
+ # atomically repair the `active` symlink with `flock` and the Windows
16
+ # junction fallback — `rm + ln -s` would race against concurrent readers
17
+ # and silently break on Windows.
18
+ updateActiveSymlinkProbeOrder:
19
+ - '{project-root}/_bmad/skf/shared/scripts/skf-update-active-symlink.py'
20
+ - '{project-root}/src/shared/scripts/skf-update-active-symlink.py'
21
+ # Resolve `{manifestOpsHelper}` similarly. §6 uses the `rename` action
22
+ # for atomic re-key (preserves `active_version`, `versions` map, all
23
+ # fields, then writes via temp + rename).
24
+ manifestOpsProbeOrder:
25
+ - '{project-root}/_bmad/skf/shared/scripts/skf-manifest-ops.py'
26
+ - '{project-root}/src/shared/scripts/skf-manifest-ops.py'
27
+ # Resolve `{rebuildManagedSectionsHelper}` similarly. §7.7 uses the
28
+ # `replace` action for the surgical between-marker rewrite.
29
+ rebuildManagedSectionsProbeOrder:
30
+ - '{project-root}/_bmad/skf/shared/scripts/skf-rebuild-managed-sections.py'
31
+ - '{project-root}/src/shared/scripts/skf-rebuild-managed-sections.py'
5
32
  ---
6
33
 
34
+ <!-- Config: communicate in {communication_language}. -->
35
+
7
36
  # Step 2: Execute Rename (Transactional)
8
37
 
9
38
  ## STEP GOAL:
10
39
 
11
- Execute the rename decisions recorded in step-01 as a transaction. Copy the old `{skill_group}` and `{forge_group}` to the new name, rename inner directories, rewrite every in-file reference, verify no trace of the old name remains inside the new location, update the export manifest, rebuild platform context files, and only then delete the old directories. Any failure before the final delete rolls back by removing the new directories — the old skill remains intact.
40
+ Execute the rename decisions recorded in step 1 as a transaction. Copy the old `{skill_group}` and `{forge_group}` to the new name, rename inner directories, rewrite every in-file reference, verify no trace of the old name remains inside the new location, update the export manifest, rebuild platform context files, and only then delete the old directories. Any failure before the final delete rolls back by removing the new directories — the old skill remains intact.
12
41
 
13
42
  ## Rules
14
43
 
15
44
  - Execute sections strictly in order — each section depends on the previous one
16
- - Do not re-prompt the user — decisions were made in step-01
45
+ - Do not re-prompt the user — decisions were made in step 1
17
46
  - Do not delete anything from old directories before section 8
18
47
  - Do not proceed past a verification failure in section 5
19
48
  - Report each section's outcome as it completes
@@ -22,15 +51,26 @@ Execute the rename decisions recorded in step-01 as a transaction. Copy the old
22
51
 
23
52
  **CRITICAL:** This is transactional. After section 1 (copy), the old skill is untouched. If any section between 2 and 7 fails, delete `{new_skill_group}` and `{new_forge_group}`, report the failure, and halt — the old skill remains intact. Only section 8 (delete old) makes the operation irreversible. Do not skip, reorder, or improvise.
24
53
 
25
- ### 0. Re-read Version-Paths Knowledge
54
+ ### 0. Re-read Version-Paths Knowledge + Resolve Helpers
26
55
 
27
56
  Read `{versionPathsKnowledge}` again and confirm the templates (`{skill_package}`, `{skill_group}`, `{forge_version}`, `{forge_group}`) and the Rename section. Also read `{managedSectionLogic}` for the managed-section format template and the skill index rebuild rules that will be reused in section 7.
28
57
 
58
+ **Resolve helpers** in parallel — these are independent file-existence checks that batch into one tool-call message:
59
+
60
+ - `{atomicWriteHelper}` ← first existing path in `{atomicWriteProbeOrder}` (used in §3, §6 for crash-safe writes)
61
+ - `{updateActiveSymlinkHelper}` ← first existing path in `{updateActiveSymlinkProbeOrder}` (used in §4 for atomic symlink repair)
62
+ - `{manifestOpsHelper}` ← first existing path in `{manifestOpsProbeOrder}` (used in §6 for the manifest re-key)
63
+ - `{rebuildManagedSectionsHelper}` ← first existing path in `{rebuildManagedSectionsProbeOrder}` (used in §7.7 for between-marker swap)
64
+
65
+ If any helper has no existing candidate, release the lock and HALT (exit code 4, `halt_reason: "write-failed"`) — the rename's safety guarantees depend on these helpers and a fall-through to LLM-driven writes would silently regress atomicity.
66
+
67
+ **Lock release contract:** every halt path in this step ends with `rm -f "{forge_data_folder}/{old_name}/.skf-rename.lock"` before exiting. The terminal health-check (step 4) is the success-path release.
68
+
29
69
  ### 1. Copy skill_group and forge_group
30
70
 
31
- **Precondition:** Both `{new_skill_group}` and `{new_forge_group}` must NOT exist (step-01 validated this in the collision check, but verify again before copying).
71
+ **Precondition:** Both `{new_skill_group}` and `{new_forge_group}` must NOT exist (step 1 validated this in the collision check, but verify again before copying).
32
72
 
33
- 1. If `{new_skill_group}` or `{new_forge_group}` exists on disk, halt with: "**Collision detected at execution time.** `{new_skill_group}` or `{new_forge_group}` now exists on disk — it did not exist during step-01 selection. Aborting before any files are touched."
73
+ 1. If `{new_skill_group}` or `{new_forge_group}` exists on disk, halt with: "**Collision detected at execution time.** `{new_skill_group}` or `{new_forge_group}` now exists on disk — it did not exist during step 1 selection. Aborting before any files are touched."
34
74
 
35
75
  2. Copy `{old_skill_group}` to `{new_skill_group}` recursively:
36
76
  - Preserve file permissions, timestamps, and symlinks
@@ -64,17 +104,24 @@ Report: "**Renamed {count} inner directories** to `{new_name}/`."
64
104
 
65
105
  For each version `v` in `affected_versions`, operate on the files inside `{new_skill_group}/{v}/{new_name}/` (the freshly renamed inner directory) and `{new_forge_group}/{v}/`:
66
106
 
107
+ **Write semantics (apply to 3a / 3b / 3c / 3d):** Compute the new file content in memory (LLM judgment work), then pipe it to `{atomicWriteHelper} write <target>` so the rewrite is staged in `<target>.skf-tmp`, fsync'd, and atomically renamed into place. A process kill or disk-full event mid-rewrite leaves the original file intact — no half-written artifacts.
108
+
109
+ ```bash
110
+ echo "{new_content}" | python3 {atomicWriteHelper} write "{target_path}"
111
+ ```
112
+
67
113
  **3a. SKILL.md frontmatter:**
68
114
 
69
115
  - Path: `{new_skill_group}/{v}/{new_name}/SKILL.md`
70
116
  - In the YAML frontmatter (between the leading `---` markers), replace the `name:` field value from `{old_name}` to `{new_name}`
71
117
  - Only replace within the frontmatter block — do not substitute matches inside the body text
118
+ - Pipe via `{atomicWriteHelper} write` per the write semantics above
72
119
  - If the file is missing, record it in `section3_warnings` and continue
73
120
 
74
121
  **3b. metadata.json:**
75
122
 
76
123
  - Path: `{new_skill_group}/{v}/{new_name}/metadata.json`
77
- - Parse the JSON, set `name` = `{new_name}`, write back preserving formatting
124
+ - Parse the JSON, set `name` = `{new_name}`, write back preserving formatting via `{atomicWriteHelper} write`
78
125
  - If the file is missing, record it in `section3_warnings` and continue
79
126
 
80
127
  **3c. context-snippet.md:**
@@ -85,36 +132,43 @@ For each version `v` in `affected_versions`, operate on the files inside `{new_s
85
132
  - Example: `root: .windsurf/skills/{old_name}/` → `root: .windsurf/skills/{new_name}/`
86
133
  - Example: `root: skills/{old_name}/` → `root: skills/{new_name}/`
87
134
  - Legacy pre-fix form `root: skills/{old_name}/active/{old_name}/` → `root: skills/{new_name}/` (normalize to flat form during rename)
135
+ - Pipe via `{atomicWriteHelper} write` per the write semantics above
88
136
  - If the file is missing, record it in `section3_warnings` and continue
89
137
 
90
138
  **3d. provenance-map.json:**
91
139
 
92
140
  - Path: `{new_forge_group}/{v}/provenance-map.json`
93
- - Parse JSON, set `skill_name` = `{new_name}`, write back preserving formatting
141
+ - Parse JSON, set `skill_name` = `{new_name}`, write back via `{atomicWriteHelper} write`
94
142
  - If the file is missing (some versions may not have a provenance map), record it in `section3_warnings` and continue
95
143
 
96
144
  **Rollback on any update failure (not just a missing file):**
97
145
 
98
146
  - `rm -rf {new_skill_group}` and `rm -rf {new_forge_group}`
99
- - Halt with: "**File update failed** at `{path}`: {error}. Rolled back both new directories. Old skill is intact."
147
+ - Release the lock: `rm -f "{forge_data_folder}/{old_name}/.skf-rename.lock"`
148
+ - Halt with: "**File update failed** at `{path}`: {error}. Rolled back both new directories. Old skill is intact." HALT (exit code 4, `halt_reason: "write-failed"`). In headless, emit the error envelope.
100
149
 
101
150
  Report: "**Updated file contents** across {affected_versions_count} version(s): SKILL.md, metadata.json, context-snippet.md, provenance-map.json."
102
151
 
103
152
  ### 4. Fix the `active` Symlink in the New Location
104
153
 
105
- Recreate or repair the `active` symlink in `{new_skill_group}`:
154
+ Recreate or repair the `active` symlink in `{new_skill_group}` via `{updateActiveSymlinkHelper}` — the helper holds an `flock` on `{new_skill_group}/active.lock`, surfaces a clear error on Windows non-dev-mode (no silent fallback), and uses the `ln -sfn tmp && mv -Tf tmp link` pattern to make the flip atomic against concurrent readers.
106
155
 
107
- 1. Inspect `{old_skill_group}/active` to determine the target version (the value the symlink points to — typically just the version string, not an absolute path)
108
- 2. Check `{new_skill_group}/active`:
109
- - If the copy in section 1 preserved it correctly and it points to the same version string → leave it as-is
110
- - If it exists but points somewhere invalid (e.g., an absolute path back into the old location) → remove and recreate it
111
- - If it is missing (some copy tools do not preserve symlinks) → create it
112
- 3. The symlink target should be a relative path: the version string alone (e.g., `0.6.0`), so that `{new_skill_group}/active/{new_name}/` resolves correctly
156
+ 1. Inspect `{old_skill_group}/active` to determine the target version (the value the symlink points to — typically just the version string, not an absolute path). If `{old_skill_group}/active` does not exist, skip this section — there is no symlink to repair.
157
+ 2. Invoke:
113
158
 
114
- **Rollback on failure:**
159
+ ```bash
160
+ python3 {updateActiveSymlinkHelper} flip-link \
161
+ --link {new_skill_group}/active \
162
+ --target {target_version}
163
+ ```
164
+
165
+ 3. The helper handles all four cases (missing, present-and-correct, present-and-stale, present-and-invalid) uniformly via atomic replace.
166
+
167
+ **Rollback on helper non-zero exit:**
115
168
 
116
169
  - `rm -rf {new_skill_group}` and `rm -rf {new_forge_group}`
117
- - Halt with: "**Failed to repair `active` symlink** in `{new_skill_group}`: {error}. Rolled back both new directories. Old skill is intact."
170
+ - Release the lock: `rm -f "{forge_data_folder}/{old_name}/.skf-rename.lock"`
171
+ - Halt with: "**Failed to repair `active` symlink** in `{new_skill_group}`: {captured stderr}. Rolled back both new directories. Old skill is intact." HALT (exit code 4, `halt_reason: "write-failed"`). In headless, emit the error envelope.
118
172
 
119
173
  ### 5. Verify — No Trace of `{old_name}` Inside the New Location
120
174
 
@@ -136,13 +190,14 @@ Also check the directory listing itself:
136
190
  **On hard failure (any structural reference to `{old_name}` remains):**
137
191
 
138
192
  - `rm -rf {new_skill_group}` and `rm -rf {new_forge_group}`
139
- - Halt with: "**Verification failed.** `{old_name}` still appears in: {list of paths}. Rolled back both new directories. Old skill is intact."
193
+ - Release the lock: `rm -f "{forge_data_folder}/{old_name}/.skf-rename.lock"`
194
+ - Halt with: "**Verification failed.** `{old_name}` still appears in: {list of paths}. Rolled back both new directories. Old skill is intact." HALT (exit code 5, `halt_reason: "verify-failed"`). In headless, emit the error envelope.
140
195
 
141
196
  Report: "**Verified** — no structural references to `{old_name}` remain inside the new location across {affected_versions_count} version(s). {if verification_warnings is non-empty: 'Informational body-text mentions retained in SKILL.md: {list}.'}"
142
197
 
143
198
  ### 6. Update Export Manifest
144
199
 
145
- **If `manifest_exists = false` (step-01 recorded no manifest on disk):**
200
+ **If `manifest_exists = false` (step 1 recorded no manifest on disk):**
146
201
 
147
202
  Skip this section entirely. Set `manifest_updated = false` and `manifest_backup = null`. There is no manifest to re-key — the skill was never exported. Section 7 will find no platform context files to rebuild either (no manifest means no prior export, so no `<!-- SKF:BEGIN -->` markers exist), and any platform file that happens to be present will be left alone by the section 2 marker check.
148
203
 
@@ -150,19 +205,21 @@ Report: "**Manifest update skipped** — no `.export-manifest.json` on disk. The
150
205
 
151
206
  **If `manifest_exists = true`:**
152
207
 
153
- 1. Load `{skills_output_folder}/.export-manifest.json`
154
- 2. **Hold a deep copy in memory** as `manifest_backup` — required for rollback in this section and section 7 on failure
155
- 3. If the manifest contains `exports.{old_name}`:
156
- - Set `exports.{new_name}` = deep copy of `exports.{old_name}` (preserving `active_version`, `versions` map, and all fields)
157
- - Delete `exports.{old_name}`
158
- 4. If the manifest does NOT contain `exports.{old_name}` (the skill was on disk but never exported), skip the re-key — the manifest has nothing to change for this skill
159
- 5. Write the updated manifest back to `{skills_output_folder}/.export-manifest.json`
208
+ 1. **Hold a deep copy in memory** as `manifest_backup` — required for rollback in this section and section 7 on failure. Read `{skills_output_folder}/.export-manifest.json` once and stash the parsed object.
209
+ 2. **Re-key via the helper.** If the manifest contains `exports.{old_name}`, invoke:
210
+
211
+ ```bash
212
+ python3 {manifestOpsHelper} {skills_output_folder} rename {old_name} {new_name}
213
+ ```
160
214
 
161
- **Rollback on write failure:**
215
+ The helper preserves `active_version`, `versions` map, and all fields, then writes the manifest atomically via temp + rename. If the manifest does NOT contain `exports.{old_name}` (the skill was on disk but never exported), skip the invocation — the manifest has nothing to change.
162
216
 
163
- - Restore the manifest from `manifest_backup` (write it back to disk)
217
+ **Rollback on helper non-zero exit:**
218
+
219
+ - Restore the manifest from `manifest_backup` via `{atomicWriteHelper} write {skills_output_folder}/.export-manifest.json` (re-pipe the JSON-serialized backup)
164
220
  - `rm -rf {new_skill_group}` and `rm -rf {new_forge_group}`
165
- - Halt with: "**Manifest update failed:** {error}. Restored manifest from backup and rolled back new directories. Old skill is intact."
221
+ - Release the lock: `rm -f "{forge_data_folder}/{old_name}/.skf-rename.lock"`
222
+ - Halt with: "**Manifest update failed:** {captured stderr}. Restored manifest from backup and rolled back new directories. Old skill is intact." HALT (exit code 4, `halt_reason: "manifest-write-failed"`). In headless, emit the error envelope.
166
223
 
167
224
  Set context flag `manifest_updated = true`.
168
225
 
@@ -170,78 +227,16 @@ Report: "**Manifest updated** — re-keyed `exports.{old_name}` → `exports.{ne
170
227
 
171
228
  ### 7. Rebuild Context Files
172
229
 
173
- Load the `ides` list from `config.yaml`. The installer writes IDE identifiersthese must be mapped to context files and skill roots using the "IDE Context File Mapping" table in `{managedSectionLogic}`.
174
-
175
- **Resolve `target_context_files`** using the canonical mapping table in `{managedSectionLogic}`:
176
-
177
- 1. For each entry in `config.yaml.ides`, look up its `context_file` and `skill_root` from the mapping table
178
- 2. For any entry not found in the table, default to AGENTS.md / `.agents/skills/` and emit a warning: "Unknown IDE '{value}' in config.yaml — defaulting to AGENTS.md"
179
- 3. Deduplicate by `context_file` — when multiple IDEs map to the same context file, use the first configured IDE's `skill_root`
180
- 4. If `config.yaml.ides` is absent or the mapping yields an empty list, fall back to `[{context_file: "AGENTS.md", skill_root: ".agents/skills/"}]` and emit a note: "No IDEs configured in config.yaml — defaulting to AGENTS.md"
181
-
182
- Store the result as `target_context_files` for this section.
183
-
184
- For each entry in `target_context_files`:
185
-
186
- 1. **Resolve target file** at `{context_file}`.
187
-
188
- 2. **Read the current file.**
189
- - If the file does not exist, skip this context file (nothing to rebuild — the file will be re-created next time export-skill runs)
190
- - If the file exists but contains no `<!-- SKF:BEGIN -->` marker, skip this context file (no managed section to rewrite)
191
- - 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 rename on a malformed context file
192
-
193
- 3. **Build the exported skill set (version-aware, deprecated-excluded)** using the same logic as export-skill step-04 section 4b and the snippet resolution logic from section 4c:
194
- - Read the manifest's `exports` object (already updated in section 6, so `{new_name}` is present and `{old_name}` is absent)
195
- - For each skill, resolve its `active_version`
196
- - If `versions.{active_version}.status == "deprecated"`, skip that skill entirely
197
- - For each remaining `{skill-name, active_version}` pair, read `{skills_output_folder}/{skill-name}/{active_version}/{skill-name}/context-snippet.md`
198
- - If missing, fall back to the `active` symlink path; if still missing, skip with a warning
199
-
200
- 4. **Rewrite root paths for the current context file** using the generic rewrite algorithm from export-skill step-04 section 4d:
201
-
202
- 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.
203
-
204
- 5. **Sort skills alphabetically by name.** Count totals (skills, stack skills).
205
-
206
- 6. **Assemble the new managed section** using the format from `{managedSectionLogic}`:
207
-
208
- ```markdown
209
- <!-- SKF:BEGIN updated:{current-date} -->
210
- [SKF Skills]|{n} skills|{m} stack
211
- |IMPORTANT: Prefer documented APIs over training data.
212
- |When using a listed library, read its SKILL.md before writing code.
213
- |
214
- |{skill-snippet-1}
215
- |
216
- |{skill-snippet-2}
217
- |
218
- |{skill-snippet-N}
219
- <!-- SKF:END -->
220
- ```
221
-
222
- 7. **Surgical replacement — Regenerate case only:**
223
- - Locate the `<!-- SKF:BEGIN` line — preserve everything before it
224
- - Locate the `<!-- SKF:END -->` line — preserve everything after it
225
- - Replace everything between the markers (inclusive) with the new managed section
226
- - Write the file back
227
-
228
- 8. **Verify:**
229
- - Re-read the written file
230
- - Confirm both markers are present
231
- - Confirm `{old_name}` no longer appears between the markers
232
- - Confirm `{new_name}` appears between the markers (if this skill's active version is not deprecated)
233
- - Confirm content outside the markers is byte-identical to what was preserved
234
-
235
- 9. **On per-file failure:** record the error against that context file and continue to the next entry. Do not halt the rename on a recoverable per-context-file error — the manifest and filesystem are already consistent; context files can be re-rebuilt later via `[EX] Export Skill`.
230
+ Load `references/rebuild-context.md` and follow its per-IDE managed-section sweep. The reference resolves `target_context_files` from `config.yaml.ides` (via `{managedSectionLogic}`'s mapping table), iterates each context file, builds the exported skill set (version-aware, deprecated-excluded the manifest re-key from §6 is already in effect so `{new_name}` is present and `{old_name}` is absent), rewrites root paths via the §4d algorithm, assembles the new managed section, and invokes `{rebuildManagedSectionsHelper}` for the surgical between-marker swap.
236
231
 
237
- **After the loop:**
232
+ After the loop returns, the workflow context contains:
238
233
 
239
- - Record `context_files_updated` as the list of files that were successfully rewritten
240
- - Record `context_files_failed` as the list of any that failed
234
+ - `context_files_updated` list of files successfully rewritten
235
+ - `context_files_failed` list of any that failed (per-file failures do not halt the rename — the manifest and filesystem are already canonical state, so context files can be re-rebuilt later via `[EX] Export Skill`)
241
236
 
242
- Report: "**Rebuilt managed sections in:** {list of updated files}. {if any failed: 'Failed: {list} — re-run `[EX] Export Skill` to retry.'}"
237
+ Report per the reference's after-loop block, then proceed to §8.
243
238
 
244
- **Note:** Section 7 failures do not trigger a rollback because the manifest and filesystem are the canonical state. Platform context files are derived artifacts that can be regenerated at any time.
239
+ **Note:** §7 failures do not trigger a rollback. Platform context files are derived artifacts; the manifest and on-disk skill directories are the canonical state.
245
240
 
246
241
  ### 8. Delete Old Directories (Point of No Return)
247
242
 
@@ -272,7 +267,7 @@ Report: "**Deleted old directories:** `{old_skill_group}` and `{old_forge_group}
272
267
 
273
268
  ### 9. Store Results in Context
274
269
 
275
- Store the following for step-03:
270
+ Store the following for step 3:
276
271
 
277
272
  - `old_name` — the previous skill name
278
273
  - `new_name` — the new skill name
@@ -0,0 +1,30 @@
1
+ ---
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
+ nextStepFile: 'shared/health-check.md'
6
+ ---
7
+
8
+ <!-- Config: communicate in {communication_language}. -->
9
+
10
+ # Step 4: Workflow Health Check
11
+
12
+ ## STEP GOAL:
13
+
14
+ Chain to the shared workflow self-improvement health check at `{nextStepFile}`. This is the terminal step of rename-skill — after the shared health check completes, the workflow is fully done.
15
+
16
+ ## Rules
17
+
18
+ - No user-facing reports, file writes, or result contracts in this step — those belong in step 3
19
+ - Delegate directly to `{nextStepFile}` with no additional commentary
20
+ - Do not attempt any other action between loading this step and executing `{nextStepFile}`
21
+
22
+ ## MANDATORY SEQUENCE
23
+
24
+ 1. **Release the rename lock.** Delete `{forge_data_folder}/{old_name}/.skf-rename.lock` if it still exists (the lock is acquired in select.md §4b and released here as the terminal cleanup). A no-op when `old_name` was never resolved or the lock was already removed by an earlier halt path.
25
+
26
+ ```bash
27
+ rm -f "{forge_data_folder}/{old_name}/.skf-rename.lock"
28
+ ```
29
+
30
+ 2. Load `{nextStepFile}`, read it fully, then execute it.