bmad-module-skill-forge 2.2.0 → 3.0.0

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 (435) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/README.md +49 -49
  3. package/docs/404.md +10 -8
  4. package/docs/_data/pinned.yaml +22 -13
  5. package/docs/_internal/STABILITY.md +58 -35
  6. package/docs/agents.md +39 -53
  7. package/docs/architecture.md +65 -51
  8. package/docs/bmad-synergy.md +53 -51
  9. package/docs/campaign.md +127 -75
  10. package/docs/concepts.md +34 -28
  11. package/docs/examples.md +70 -68
  12. package/docs/forge-auto.md +34 -31
  13. package/docs/getting-started.md +118 -57
  14. package/docs/how-it-works.md +25 -21
  15. package/docs/index.md +15 -15
  16. package/docs/skill-model.md +70 -59
  17. package/docs/troubleshooting.md +135 -18
  18. package/docs/verifying-a-skill.md +83 -57
  19. package/docs/why-skf.md +24 -22
  20. package/docs/workflows.md +274 -110
  21. package/package.json +18 -10
  22. package/src/forger/preferences.yaml +8 -1
  23. package/src/knowledge/agentskills-spec.md +2 -0
  24. package/src/knowledge/ccc-bridge.md +40 -24
  25. package/src/knowledge/confidence-tiers.md +9 -5
  26. package/src/knowledge/overview.md +3 -3
  27. package/src/knowledge/progressive-capability.md +8 -8
  28. package/src/knowledge/provenance-tracking.md +9 -5
  29. package/src/knowledge/qmd-registry.md +2 -2
  30. package/src/knowledge/skf-knowledge-index.csv +2 -2
  31. package/src/knowledge/skill-lifecycle.md +18 -11
  32. package/src/knowledge/split-body-strategy.md +0 -3
  33. package/src/knowledge/tool-resolution.md +4 -2
  34. package/src/knowledge/version-paths.md +101 -15
  35. package/src/module-help.csv +3 -3
  36. package/src/module.yaml +10 -0
  37. package/src/shared/data/ast-grep-recipes.yaml +608 -0
  38. package/src/shared/data/ide-context-files.json +30 -0
  39. package/src/shared/health-check.md +32 -12
  40. package/src/shared/references/description-guard-protocol.md +12 -9
  41. package/src/shared/references/feasibility-report-schema.md +19 -13
  42. package/src/shared/references/headless-gate-convention.md +55 -3
  43. package/src/shared/references/output-contract-schema.md +19 -8
  44. package/src/shared/references/pipeline-contracts.md +94 -29
  45. package/src/shared/references/tessl-review.md +77 -0
  46. package/src/shared/scripts/schemas/skf-analyze-result-envelope.v1.json +194 -0
  47. package/src/shared/scripts/schemas/skf-audit-result-envelope.v1.json +192 -0
  48. package/src/shared/scripts/schemas/skf-brief-result-envelope.v1.json +32 -4
  49. package/src/shared/scripts/schemas/skf-campaign-result-envelope.v1.json +174 -0
  50. package/src/shared/scripts/schemas/skf-create-skill-result-envelope.v1.json +284 -0
  51. package/src/shared/scripts/schemas/skf-drop-skill-result-envelope.v1.json +164 -0
  52. package/src/shared/scripts/schemas/skf-export-result-envelope.v1.json +160 -0
  53. package/src/shared/scripts/schemas/skf-quick-skill-result-envelope.v1.json +261 -0
  54. package/src/shared/scripts/schemas/skf-refine-architecture-result-envelope.v1.json +192 -0
  55. package/src/shared/scripts/schemas/skf-rename-skill-result-envelope.v1.json +179 -0
  56. package/src/shared/scripts/schemas/skf-setup-result-envelope.v1.json +27 -11
  57. package/src/shared/scripts/schemas/skf-stack-result-envelope.v1.json +176 -0
  58. package/src/shared/scripts/schemas/skf-test-result-envelope.v1.json +173 -0
  59. package/src/shared/scripts/schemas/skf-update-result-envelope.v1.json +19 -5
  60. package/src/shared/scripts/schemas/skf-verify-stack-result-envelope.v1.json +180 -0
  61. package/src/shared/scripts/schemas/skill-brief.v1.json +34 -0
  62. package/src/shared/scripts/schemas/workspace-detection.v1.json +1 -1
  63. package/src/shared/scripts/skf-atomic-write.py +30 -14
  64. package/src/shared/scripts/skf-build-change-manifest.py +2203 -24
  65. package/src/shared/scripts/skf-ccc-git-hygiene.py +532 -0
  66. package/src/shared/scripts/skf-check-unit-records.py +184 -0
  67. package/src/shared/scripts/skf-check-workspace-drift.py +538 -9
  68. package/src/shared/scripts/skf-classify-changed-files.py +694 -0
  69. package/src/shared/scripts/skf-comention-pairs.py +1333 -123
  70. package/src/shared/scripts/skf-compare-file-hashes.py +1 -1
  71. package/src/shared/scripts/skf-count-imports.py +1867 -0
  72. package/src/shared/scripts/skf-count-tokens.py +1 -1
  73. package/src/shared/scripts/skf-derive-assembly-shape.py +3 -2
  74. package/src/shared/scripts/skf-description-guard.py +99 -11
  75. package/src/shared/scripts/skf-detect-docs.py +694 -2
  76. package/src/shared/scripts/skf-detect-language.py +486 -107
  77. package/src/shared/scripts/skf-detect-registry.py +887 -0
  78. package/src/shared/scripts/skf-detect-scripts-assets.py +1 -1
  79. package/src/shared/scripts/skf-detect-tools.py +209 -27
  80. package/src/shared/scripts/skf-detect-workspaces.py +506 -30
  81. package/src/shared/scripts/skf-disqualify-candidates.py +821 -182
  82. package/src/shared/scripts/skf-emit-brief-result-envelope.py +69 -191
  83. package/src/shared/scripts/skf-emit-result-envelope.py +1604 -106
  84. package/src/shared/scripts/skf-enumerate-stack-skills.py +986 -117
  85. package/src/shared/scripts/skf-extract-public-api.py +4084 -85
  86. package/src/shared/scripts/skf-extraction-inventory.py +746 -0
  87. package/src/shared/scripts/skf-extraction-snapshot.py +539 -0
  88. package/src/shared/scripts/skf-fetch-temporal.py +674 -0
  89. package/src/shared/scripts/skf-find-cycles.py +97 -29
  90. package/src/shared/scripts/skf-find-test-report.py +476 -0
  91. package/src/shared/scripts/skf-forge-tier-rw.py +444 -203
  92. package/src/shared/scripts/skf-github-fetch.py +365 -0
  93. package/src/shared/scripts/skf-github-probe.py +661 -0
  94. package/src/shared/scripts/skf-hash-content.py +166 -12
  95. package/src/shared/scripts/skf-language-corpora.py +1 -1
  96. package/src/shared/scripts/skf-load-provenance.py +159 -27
  97. package/src/shared/scripts/skf-manifest-ops.py +1 -1
  98. package/src/shared/scripts/skf-merge-ccc-exclusions.py +2307 -223
  99. package/src/shared/scripts/skf-merge-doc-urls.py +1 -1
  100. package/src/shared/scripts/skf-names-present.py +221 -0
  101. package/src/shared/scripts/skf-pair-intersect.py +119 -28
  102. package/src/shared/scripts/skf-parse-gaps.py +1384 -0
  103. package/src/shared/scripts/skf-preapply.py +1 -1
  104. package/src/shared/scripts/skf-preflight.py +161 -27
  105. package/src/shared/scripts/skf-promote-staged.py +430 -0
  106. package/src/shared/scripts/skf-provenance-gap-dispatch.py +39 -7
  107. package/src/shared/scripts/skf-qmd-classify-collections.py +229 -45
  108. package/src/shared/scripts/skf-quick-batch.py +774 -0
  109. package/src/shared/scripts/skf-rebuild-managed-sections.py +972 -88
  110. package/src/shared/scripts/skf-recommend-scope-type.py +323 -156
  111. package/src/shared/scripts/skf-render-metadata-stats.py +156 -12
  112. package/src/shared/scripts/skf-render-quick-metadata.py +132 -28
  113. package/src/shared/scripts/skf-render-stack-metadata.py +976 -0
  114. package/src/shared/scripts/skf-resolve-authoritative-files.py +128 -13
  115. package/src/shared/scripts/skf-resolve-package.py +523 -106
  116. package/src/shared/scripts/skf-rewrite-skill-name.py +433 -47
  117. package/src/shared/scripts/skf-run-lock.py +577 -0
  118. package/src/shared/scripts/skf-scan-manifests.py +998 -57
  119. package/src/shared/scripts/skf-scan-skill-md-structure.py +1341 -37
  120. package/src/shared/scripts/skf-severity-classify.py +712 -108
  121. package/src/shared/scripts/skf-shape-detect.py +298 -204
  122. package/src/shared/scripts/skf-shard-body.py +9 -8
  123. package/src/shared/scripts/skf-skill-inventory.py +2412 -89
  124. package/src/shared/scripts/skf-skills-module.py +472 -0
  125. package/src/shared/scripts/skf-source-tree.py +1796 -0
  126. package/src/shared/scripts/skf-structural-diff.py +670 -119
  127. package/src/shared/scripts/skf-tessl-review.py +706 -0
  128. package/src/shared/scripts/skf-update-active-symlink.py +5 -5
  129. package/src/shared/scripts/skf-update-run-state.py +624 -0
  130. package/src/shared/scripts/skf-validate-brief-inputs.py +92 -29
  131. package/src/shared/scripts/skf-validate-brief-schema.py +4 -1
  132. package/src/shared/scripts/skf-validate-feasibility-report.py +577 -66
  133. package/src/shared/scripts/skf-validate-frontmatter.py +103 -26
  134. package/src/shared/scripts/skf-validate-output.py +712 -64
  135. package/src/shared/scripts/skf-validate-pins.py +1 -1
  136. package/src/shared/scripts/skf-verify-no-trace.py +116 -10
  137. package/src/shared/scripts/skf-verify-provenance-completeness.py +2919 -54
  138. package/src/shared/scripts/skf-write-skill-brief.py +367 -19
  139. package/src/shared/tool-requirements.yaml +201 -0
  140. package/src/skf-analyze-source/SKILL.md +41 -36
  141. package/src/skf-analyze-source/assets/skill-brief-schema.md +7 -8
  142. package/src/skf-analyze-source/customize.toml +36 -24
  143. package/src/skf-analyze-source/references/auto-docs-only.md +58 -20
  144. package/src/skf-analyze-source/references/continue.md +2 -13
  145. package/src/skf-analyze-source/references/discover-additional-source.md +147 -0
  146. package/src/skf-analyze-source/references/generate-briefs.md +121 -55
  147. package/src/skf-analyze-source/references/headless-contract.md +42 -15
  148. package/src/skf-analyze-source/references/identify-units.md +96 -110
  149. package/src/skf-analyze-source/references/init.md +73 -71
  150. package/src/skf-analyze-source/references/map-and-detect.md +123 -105
  151. package/src/skf-analyze-source/references/map-unit-exports.md +68 -0
  152. package/src/skf-analyze-source/references/recommend.md +51 -70
  153. package/src/skf-analyze-source/references/scan-project.md +60 -84
  154. package/src/skf-analyze-source/references/scan-root.md +39 -0
  155. package/src/skf-analyze-source/references/step-auto-scope-coexistence.md +47 -0
  156. package/src/skf-analyze-source/references/step-auto-scope-corpora.md +53 -0
  157. package/src/skf-analyze-source/references/step-auto-scope-split.md +91 -0
  158. package/src/skf-analyze-source/references/step-auto-scope.md +208 -293
  159. package/src/skf-analyze-source/references/step-shape-detect.md +14 -12
  160. package/src/skf-analyze-source/references/unit-detection-heuristics.md +37 -42
  161. package/src/skf-audit-skill/SKILL.md +43 -51
  162. package/src/skf-audit-skill/assets/drift-report-template.md +27 -3
  163. package/src/skf-audit-skill/customize.toml +41 -20
  164. package/src/skf-audit-skill/references/constituent-freshness.md +91 -0
  165. package/src/skf-audit-skill/references/doc-drift.md +141 -0
  166. package/src/skf-audit-skill/references/headless-contract.md +29 -0
  167. package/src/skf-audit-skill/references/init.md +148 -210
  168. package/src/skf-audit-skill/references/re-index.md +96 -108
  169. package/src/skf-audit-skill/references/report.md +96 -33
  170. package/src/skf-audit-skill/references/semantic-diff.md +27 -18
  171. package/src/skf-audit-skill/references/severity-classify.md +79 -65
  172. package/src/skf-audit-skill/references/severity-rules.md +15 -6
  173. package/src/skf-audit-skill/references/structural-diff.md +75 -90
  174. package/src/skf-audit-skill/references/upstream-checkout.md +77 -0
  175. package/src/skf-audit-skill/scripts/render-drift-tables.py +685 -0
  176. package/src/skf-brief-skill/SKILL.md +36 -25
  177. package/src/skf-brief-skill/assets/description-voice-examples.md +1 -1
  178. package/src/skf-brief-skill/assets/scope-templates.md +17 -24
  179. package/src/skf-brief-skill/assets/skill-brief-schema.md +29 -15
  180. package/src/skf-brief-skill/customize.toml +48 -20
  181. package/src/skf-brief-skill/references/analyze-target.md +142 -125
  182. package/src/skf-brief-skill/references/confirm-brief.md +10 -8
  183. package/src/skf-brief-skill/references/draft-checkpoint.md +36 -17
  184. package/src/skf-brief-skill/references/gather-intent-ratify.md +68 -0
  185. package/src/skf-brief-skill/references/gather-intent.md +87 -182
  186. package/src/skf-brief-skill/references/headless-args.md +84 -16
  187. package/src/skf-brief-skill/references/health-check.md +1 -1
  188. package/src/skf-brief-skill/references/invocation-contract.md +18 -13
  189. package/src/skf-brief-skill/references/portfolio-similarity-check.md +1 -1
  190. package/src/skf-brief-skill/references/qmd-collection-registration.md +7 -10
  191. package/src/skf-brief-skill/references/scope-definition.md +123 -47
  192. package/src/skf-brief-skill/references/step-auto-brief.md +24 -80
  193. package/src/skf-brief-skill/references/step-auto-validate.md +20 -121
  194. package/src/skf-brief-skill/references/version-resolution.md +3 -2
  195. package/src/skf-brief-skill/references/write-brief.md +66 -57
  196. package/src/skf-campaign/SKILL.md +31 -34
  197. package/src/skf-campaign/assets/campaign-state-schema.json +25 -4
  198. package/src/skf-campaign/customize.toml +47 -16
  199. package/src/skf-campaign/references/campaign-contracts.md +39 -29
  200. package/src/skf-campaign/references/campaign-directive-spec.md +4 -2
  201. package/src/skf-campaign/references/health-check.md +7 -16
  202. package/src/skf-campaign/references/step-01-setup.md +46 -84
  203. package/src/skf-campaign/references/step-02-strategy.md +31 -30
  204. package/src/skf-campaign/references/step-03-pins.md +26 -18
  205. package/src/skf-campaign/references/step-04-provenance.md +24 -23
  206. package/src/skf-campaign/references/step-05-skill-loop.md +67 -48
  207. package/src/skf-campaign/references/step-06-batch.md +41 -34
  208. package/src/skf-campaign/references/step-07-capstone.md +40 -25
  209. package/src/skf-campaign/references/step-08-verify.md +28 -29
  210. package/src/skf-campaign/references/step-09-refine.md +29 -30
  211. package/src/skf-campaign/references/step-10-export.md +48 -36
  212. package/src/skf-campaign/references/step-11-maintenance.md +31 -34
  213. package/src/skf-campaign/references/step-resume.md +37 -68
  214. package/src/skf-campaign/scripts/campaign-deps.py +57 -18
  215. package/src/skf-campaign/scripts/campaign-parse-manifest.py +361 -54
  216. package/src/skf-campaign/scripts/campaign-provenance.py +96 -53
  217. package/src/skf-campaign/scripts/campaign-quality-gate.py +592 -0
  218. package/src/skf-campaign/scripts/campaign-render-batch.py +257 -49
  219. package/src/skf-campaign/scripts/campaign-render-kickoff.py +343 -50
  220. package/src/skf-campaign/scripts/campaign-report.py +204 -37
  221. package/src/skf-campaign/scripts/campaign-state.py +1128 -0
  222. package/src/skf-campaign/scripts/campaign-status.py +10 -74
  223. package/src/skf-campaign/scripts/campaign-validate-pins.py +30 -3
  224. package/src/skf-campaign/scripts/campaign-validate-state.py +34 -4
  225. package/src/skf-campaign/templates/campaign-brief-template.yaml +4 -5
  226. package/src/skf-campaign/templates/campaign-report-template.md +5 -1
  227. package/src/skf-campaign/templates/kickoff-template.md +0 -14
  228. package/src/skf-create-skill/SKILL.md +27 -20
  229. package/src/skf-create-skill/assets/compile-assembly-rules.md +6 -5
  230. package/src/skf-create-skill/assets/skill-sections.md +15 -5
  231. package/src/skf-create-skill/customize.toml +20 -8
  232. package/src/skf-create-skill/references/authoritative-files-protocol.md +41 -42
  233. package/src/skf-create-skill/references/batch-mode.md +81 -0
  234. package/src/skf-create-skill/references/ccc-index-check.md +27 -0
  235. package/src/skf-create-skill/references/compile.md +107 -29
  236. package/src/skf-create-skill/references/component-extraction.md +113 -91
  237. package/src/skf-create-skill/references/enrich.md +41 -23
  238. package/src/skf-create-skill/references/entry-points-by-hand.md +20 -0
  239. package/src/skf-create-skill/references/extract.md +200 -161
  240. package/src/skf-create-skill/references/extraction-patterns-by-hand.md +141 -0
  241. package/src/skf-create-skill/references/extraction-patterns-tracing.md +2 -2
  242. package/src/skf-create-skill/references/extraction-patterns.md +584 -196
  243. package/src/skf-create-skill/references/generate-artifacts.md +145 -93
  244. package/src/skf-create-skill/references/health-check.md +1 -1
  245. package/src/skf-create-skill/references/load-brief.md +53 -36
  246. package/src/skf-create-skill/references/relabel-rule.md +12 -0
  247. package/src/skf-create-skill/references/report.md +28 -59
  248. package/src/skf-create-skill/references/source-resolution-protocols.md +49 -155
  249. package/src/skf-create-skill/references/step-auto-shard.md +20 -93
  250. package/src/skf-create-skill/references/step-doc-rot.md +44 -60
  251. package/src/skf-create-skill/references/step-doc-sources.md +28 -19
  252. package/src/skf-create-skill/references/sub/ccc-discover.md +18 -7
  253. package/src/skf-create-skill/references/sub/fetch-docs.md +106 -59
  254. package/src/skf-create-skill/references/sub/fetch-temporal.md +53 -166
  255. package/src/skf-create-skill/references/tier-degradation-rules.md +18 -9
  256. package/src/skf-create-skill/references/validate.md +173 -99
  257. package/src/skf-create-skill/scripts/scan-doc-rot.py +232 -99
  258. package/src/skf-create-stack-skill/SKILL.md +29 -56
  259. package/src/skf-create-stack-skill/assets/metadata-contract.md +51 -0
  260. package/src/skf-create-stack-skill/assets/provenance-map-schema.md +15 -15
  261. package/src/skf-create-stack-skill/assets/stack-skill-template.md +23 -57
  262. package/src/skf-create-stack-skill/customize.toml +23 -12
  263. package/src/skf-create-stack-skill/references/compile-stack.md +57 -66
  264. package/src/skf-create-stack-skill/references/compose-mode-rules.md +24 -44
  265. package/src/skf-create-stack-skill/references/detect-integrations.md +92 -95
  266. package/src/skf-create-stack-skill/references/detect-manifests.md +46 -71
  267. package/src/skf-create-stack-skill/references/generate-output.md +138 -128
  268. package/src/skf-create-stack-skill/references/init.md +90 -32
  269. package/src/skf-create-stack-skill/references/integration-patterns.md +1 -17
  270. package/src/skf-create-stack-skill/references/invocation-contract.md +34 -0
  271. package/src/skf-create-stack-skill/references/manifest-patterns.md +32 -20
  272. package/src/skf-create-stack-skill/references/parallel-extract.md +112 -38
  273. package/src/skf-create-stack-skill/references/rank-and-confirm.md +57 -75
  274. package/src/skf-create-stack-skill/references/report.md +39 -33
  275. package/src/skf-create-stack-skill/references/validate.md +20 -39
  276. package/src/skf-drop-skill/SKILL.md +28 -51
  277. package/src/skf-drop-skill/customize.toml +44 -30
  278. package/src/skf-drop-skill/references/execute.md +79 -146
  279. package/src/skf-drop-skill/references/invocation-contract.md +64 -0
  280. package/src/skf-drop-skill/references/report.md +46 -30
  281. package/src/skf-drop-skill/references/select.md +118 -124
  282. package/src/skf-drop-skill/scripts/dir-sizes.py +54 -26
  283. package/src/skf-drop-skill/scripts/drop-roster.py +322 -0
  284. package/src/skf-export-skill/SKILL.md +40 -62
  285. package/src/skf-export-skill/assets/managed-section-format.md +14 -50
  286. package/src/skf-export-skill/assets/snippet-format.md +3 -1
  287. package/src/skf-export-skill/customize.toml +42 -13
  288. package/src/skf-export-skill/references/generate-snippet.md +54 -46
  289. package/src/skf-export-skill/references/health-check.md +2 -0
  290. package/src/skf-export-skill/references/invocation-contract.md +15 -0
  291. package/src/skf-export-skill/references/load-skill.md +88 -62
  292. package/src/skf-export-skill/references/manifest-rebuild.md +9 -10
  293. package/src/skf-export-skill/references/multi-skill-mode.md +4 -4
  294. package/src/skf-export-skill/references/orphan-context-detection.md +13 -5
  295. package/src/skf-export-skill/references/orphan-row-detection.md +31 -22
  296. package/src/skf-export-skill/references/package.md +15 -73
  297. package/src/skf-export-skill/references/preflight-snippet-root-probe.md +51 -70
  298. package/src/skf-export-skill/references/result-envelope.md +31 -16
  299. package/src/skf-export-skill/references/summary.md +41 -17
  300. package/src/skf-export-skill/references/token-report.md +4 -12
  301. package/src/skf-export-skill/references/update-context.md +118 -237
  302. package/src/skf-forger/SKILL.md +61 -37
  303. package/src/skf-forger/bmad-skill-manifest.yaml +4 -1
  304. package/src/skf-forger/customize.toml +43 -0
  305. package/src/skf-forger/references/pipeline-mode.md +73 -18
  306. package/src/skf-forger/scripts/forge-status.py +299 -0
  307. package/src/skf-forger/scripts/parse-pipeline.py +322 -54
  308. package/src/skf-forger/scripts/pipeline-gate.py +428 -0
  309. package/src/skf-forger/scripts/pipeline-journal.py +1052 -0
  310. package/src/skf-quick-skill/SKILL.md +54 -53
  311. package/src/skf-quick-skill/assets/skill-template.md +4 -2
  312. package/src/skf-quick-skill/customize.toml +51 -20
  313. package/src/skf-quick-skill/references/batch-mode.md +74 -21
  314. package/src/skf-quick-skill/references/compile.md +30 -31
  315. package/src/skf-quick-skill/references/ecosystem-check.md +7 -57
  316. package/src/skf-quick-skill/references/finalize.md +69 -18
  317. package/src/skf-quick-skill/references/halt-contract.md +41 -29
  318. package/src/skf-quick-skill/references/health-check.md +5 -3
  319. package/src/skf-quick-skill/references/quick-extract.md +114 -45
  320. package/src/skf-quick-skill/references/registry-resolution.md +9 -64
  321. package/src/skf-quick-skill/references/resolve-target.md +116 -66
  322. package/src/skf-quick-skill/references/write-and-validate.md +79 -40
  323. package/src/skf-refine-architecture/SKILL.md +43 -53
  324. package/src/skf-refine-architecture/customize.toml +49 -20
  325. package/src/skf-refine-architecture/references/compile.md +97 -54
  326. package/src/skf-refine-architecture/references/exit-codes.md +30 -0
  327. package/src/skf-refine-architecture/references/finding-storage.md +21 -0
  328. package/src/skf-refine-architecture/references/gap-analysis.md +101 -38
  329. package/src/skf-refine-architecture/references/improvements.md +14 -20
  330. package/src/skf-refine-architecture/references/init.md +98 -57
  331. package/src/skf-refine-architecture/references/issue-detection.md +32 -39
  332. package/src/skf-refine-architecture/references/refinement-rules.md +37 -48
  333. package/src/skf-refine-architecture/references/report.md +65 -54
  334. package/src/skf-refine-architecture/scripts/skf-check-preservation.py +1619 -0
  335. package/src/skf-rename-skill/SKILL.md +19 -54
  336. package/src/skf-rename-skill/customize.toml +32 -26
  337. package/src/skf-rename-skill/references/execute.md +230 -184
  338. package/src/skf-rename-skill/references/exit-codes.md +7 -7
  339. package/src/skf-rename-skill/references/health-check.md +1 -7
  340. package/src/skf-rename-skill/references/invocation-contract.md +25 -0
  341. package/src/skf-rename-skill/references/report.md +63 -52
  342. package/src/skf-rename-skill/references/select.md +197 -115
  343. package/src/skf-rename-skill/scripts/skf-validate-rename-name.py +161 -21
  344. package/src/skf-setup/SKILL.md +26 -26
  345. package/src/skf-setup/customize.toml +14 -10
  346. package/src/skf-setup/references/auto-index.md +50 -63
  347. package/src/skf-setup/references/ccc-index.md +29 -90
  348. package/src/skf-setup/references/detect-and-tier.md +58 -67
  349. package/src/skf-setup/references/health-check.md +2 -0
  350. package/src/skf-setup/references/invocation-contract.md +14 -0
  351. package/src/skf-setup/references/report.md +43 -166
  352. package/src/skf-setup/references/tier-rules.md +5 -5
  353. package/src/skf-setup/references/write-config.md +34 -57
  354. package/src/skf-test-skill/SKILL.md +17 -57
  355. package/src/skf-test-skill/assets/output-section-formats.md +33 -34
  356. package/src/skf-test-skill/customize.toml +27 -13
  357. package/src/skf-test-skill/references/coherence-check.md +134 -62
  358. package/src/skf-test-skill/references/coverage-check-tiers.md +35 -0
  359. package/src/skf-test-skill/references/coverage-check.md +217 -254
  360. package/src/skf-test-skill/references/detect-mode.md +5 -5
  361. package/src/skf-test-skill/references/external-validators.md +94 -82
  362. package/src/skf-test-skill/references/health-check.md +6 -7
  363. package/src/skf-test-skill/references/init.md +163 -88
  364. package/src/skf-test-skill/references/invocation-contract.md +66 -0
  365. package/src/skf-test-skill/references/migration-section-rules.md +5 -2
  366. package/src/skf-test-skill/references/report.md +162 -142
  367. package/src/skf-test-skill/references/score.md +80 -107
  368. package/src/skf-test-skill/references/scoring-rules.md +41 -155
  369. package/src/skf-test-skill/references/source-access-protocol.md +19 -92
  370. package/src/skf-test-skill/references/step-hard-gate.md +51 -33
  371. package/src/skf-test-skill/scripts/aggregate-coherence.py +218 -30
  372. package/src/skf-test-skill/scripts/build-result-context.py +287 -0
  373. package/src/skf-test-skill/scripts/check-metadata-coherence.py +37 -4
  374. package/src/skf-test-skill/scripts/combine-external-scores.py +23 -6
  375. package/src/skf-test-skill/scripts/compute-score.py +223 -45
  376. package/src/skf-test-skill/scripts/gap-ledger.py +1381 -0
  377. package/src/skf-test-skill/scripts/hard-gate.py +203 -0
  378. package/src/skf-test-skill/scripts/load-coverage-inputs.py +760 -0
  379. package/src/skf-test-skill/scripts/locate-export-segments.py +835 -0
  380. package/src/skf-test-skill/scripts/reconcile-coverage.py +273 -79
  381. package/src/skf-test-skill/scripts/score-signatures.py +459 -0
  382. package/src/skf-test-skill/scripts/stage-helper-payload.py +148 -0
  383. package/src/skf-test-skill/scripts/validate-inventory.py +311 -16
  384. package/src/skf-test-skill/scripts/verify-declared-numerator.py +127 -52
  385. package/src/skf-test-skill/templates/test-report-template.md +21 -15
  386. package/src/skf-update-skill/SKILL.md +38 -25
  387. package/src/skf-update-skill/customize.toml +27 -12
  388. package/src/skf-update-skill/references/detect-changes.md +233 -222
  389. package/src/skf-update-skill/references/gap-driven.md +336 -0
  390. package/src/skf-update-skill/references/health-check.md +31 -5
  391. package/src/skf-update-skill/references/init.md +250 -84
  392. package/src/skf-update-skill/references/invocation-contract.md +12 -0
  393. package/src/skf-update-skill/references/manual-section-rules.md +6 -23
  394. package/src/skf-update-skill/references/merge.md +180 -47
  395. package/src/skf-update-skill/references/re-extract.md +53 -262
  396. package/src/skf-update-skill/references/report.md +100 -35
  397. package/src/skf-update-skill/references/write.md +331 -149
  398. package/src/skf-update-skill/scripts/skf-new-file-diff.py +29 -7
  399. package/src/skf-verify-stack/SKILL.md +23 -42
  400. package/src/skf-verify-stack/assets/feasibility-report-template.md +11 -5
  401. package/src/skf-verify-stack/customize.toml +55 -22
  402. package/src/skf-verify-stack/references/coverage-patterns.md +17 -8
  403. package/src/skf-verify-stack/references/coverage.md +67 -64
  404. package/src/skf-verify-stack/references/exit-codes.md +21 -8
  405. package/src/skf-verify-stack/references/init.md +107 -62
  406. package/src/skf-verify-stack/references/integration-verification-rules.md +12 -13
  407. package/src/skf-verify-stack/references/integrations.md +106 -65
  408. package/src/skf-verify-stack/references/report.md +59 -42
  409. package/src/skf-verify-stack/references/requirements.md +32 -9
  410. package/src/skf-verify-stack/references/synthesize.md +53 -39
  411. package/src/skf-verify-stack/scripts/skf-coverage-tally.py +398 -52
  412. package/src/skf-verify-stack/scripts/skf-previous-report.py +330 -0
  413. package/src/skf-verify-stack/scripts/skf-report-delta.py +453 -49
  414. package/src/skf-verify-stack/scripts/skf-verdict-rollup.py +240 -27
  415. package/tools/cli/commands/install.js +11 -4
  416. package/tools/cli/commands/status.js +15 -3
  417. package/tools/cli/commands/update.js +11 -4
  418. package/tools/cli/lib/tool-check.js +320 -0
  419. package/tools/cli/lib/version-check.js +22 -9
  420. package/tools/cli/skf-cli.js +4 -1
  421. package/.gitattributes +0 -16
  422. package/.nvmrc +0 -1
  423. package/docs/_internal/RELEASING.md +0 -679
  424. package/release-audits/v1.0.0-launch-audit.md +0 -728
  425. package/src/skf-audit-skill/references/step-doc-drift.md +0 -177
  426. package/src/skf-brief-skill/references/headless-source-authority-detection.md +0 -26
  427. package/src/skf-campaign/manifest.yaml +0 -15
  428. package/src/skf-create-skill/assets/tessl-dismissal-rules.md +0 -106
  429. package/src/skf-create-skill/references/ecosystem-check.md +0 -74
  430. package/src/skf-drop-skill/references/headless-contract.md +0 -18
  431. package/src/skf-update-skill/references/merge-conflict-rules.md +0 -15
  432. package/src/skf-update-skill/references/remote-source-resolution.md +0 -98
  433. package/src/skf-update-skill/references/validate.md +0 -124
  434. package/tools/validate-docs-drift.js +0 -233
  435. package/tools/validate-docs-links.js +0 -665
@@ -6,8 +6,8 @@ Bridge names (`ast_bridge`, `ccc_bridge`, `qmd_bridge`, `gh_bridge`) and subproc
6
6
 
7
7
  | Bridge | Operation | Claude Code | Cursor | CLI | Fallback |
8
8
  |--------------|----------------------------------|------------------------------------------------------------------|----------------|----------------------------------------------------|----------------------------------|
9
- | `ast_bridge` | `scan_definitions()` | `mcp__ast-grep__find_code` or `mcp__ast-grep__find_code_by_rule` | ast-grep MCP | `sg run` / `ast-grep -p` | Source reading (T1-low) |
10
- | `ast_bridge` | `detect_co_imports()` | `mcp__ast-grep__find_code_by_rule` with co-import YAML rule | ast-grep MCP | `ast-grep run -p 'import $$$' --json=stream` | grep-based co-import count |
9
+ | `ast_bridge` | `scan_definitions()` | `mcp__ast-grep__find_code_by_rule` with each recipe, `output_format="json"`; `mcp__ast-grep__find_code` only as the fallback | ast-grep MCP | `ast-grep scan -r {recipe_file} --json=stream` | Source reading (T1-low) |
10
+ | `ast_bridge` | `detect_co_imports()` | `mcp__ast-grep__find_code_by_rule` with co-import YAML rule | ast-grep MCP | `ast-grep scan -r {rule_file} --json=stream` | grep-based co-import count |
11
11
  | `ccc_bridge` | `search(query, root, top_k)` | `/ccc` skill search | ccc MCP server | `cd {root} && ccc search --limit {top_k} "{query}"` | Skip silently |
12
12
  | `ccc_bridge` | `ensure_index(root)` | `/ccc` skill indexing | ccc MCP server | `cd {root} && ccc init` + `ccc index` | Skip silently |
13
13
  | `ccc_bridge` | `status()` | `/ccc` skill status | ccc MCP server | `ccc --help` + `ccc doctor` | Unavailable = `tools.ccc: false` |
@@ -17,6 +17,8 @@ Bridge names (`ast_bridge`, `ccc_bridge`, `qmd_bridge`, `gh_bridge`) and subproc
17
17
  | `gh_bridge` | `list_tree(owner, repo, branch)` | `gh api repos/{owner}/{repo}/git/trees/{branch}?recursive=1` | gh CLI | `gh api ...` | Direct file listing if local |
18
18
  | `gh_bridge` | `read_file(owner, repo, path)` | `gh api repos/{owner}/{repo}/contents/{path}` | gh CLI | `gh api ...` | Direct file read if local |
19
19
 
20
+ `scan_definitions()` follows the AST Extraction Protocol in create-skill's `extraction-patterns.md`, which holds the recipes: where the step gives the recipe runner's command (`skf-extract-public-api.py --mode full`), it runs them all in one call; otherwise, and when the runner cannot run, the protocol's decision tree, not the priority order below, picks between the MCP call and the CLI template, and `find_code` serves only as its Known Limitation #4 fallback.
21
+
20
22
  ## Subprocess Pattern Definitions
21
23
 
22
24
  Workflow steps reference "subprocess" execution with numbered patterns. These map to concrete mechanisms per IDE:
@@ -94,17 +94,34 @@ The inner `{skill-name}/` directory IS the agentskills.io-compliant skill packag
94
94
  provenance-map.json
95
95
  evidence-report.md
96
96
  extraction-rules.yaml
97
- test-report-{skill-name}.md
97
+ evidence-report-fallback.md
98
+ extraction-snapshot.json
99
+ .test-skill.lock
100
+ .skf-test-report-{skill-name}-{run_id}.md
101
+ test-report-{skill-name}-{run_id}.md
102
+ test-findings-{run_id}.json
103
+ drift-report-{timestamp}.md
104
+ .skf-audit/{timestamp}/
105
+ manual-backup/SKILL-{timestamp}.md
106
+ {workflow}-result-{timestamp}.json
107
+ {workflow}-result-latest.json
108
+ _campaign/
109
+ improvement-queue/
98
110
  ```
99
111
 
100
112
  `skill-brief.yaml` stays at `{forge_group}` level — the brief is a workflow input that defines extraction scope, not a versioned output.
101
113
 
114
+ `test-findings-{run_id}.json` is test-skill's gap ledger, beside the test report of the same run. test-skill writes that report as `.skf-test-report-{skill-name}-{run_id}.md` while it runs and renames it to `test-report-{skill-name}-{run_id}.md` once its checks pass, so a halted run leaves only the hidden name, which no consumer reads. `.skf-audit/{timestamp}/` holds audit-skill's stage data for the drift report of the same timestamp: the scan list, the recipe runner's extraction and the exports read by eye (`scan-files.json`, `extraction.json`, one `export-details-{n}.json` per worker), `structural-diff.json`, the relocation check's candidates and finds (`relocation-candidates.json`, `relocations.json`), `file-drift.json`, `semantic-findings.json` or, for a compose-mode stack, `constituent-freshness.json`, then `findings.json` and `severity.json`. `manual-backup/` holds an earlier `SKILL.md` that create-skill's promotion kept (`skf-promote-staged.py --carry-manual`) because a re-run of the version lacked one of its hand-written `[MANUAL]` blocks, one file per run that needed it.
115
+
116
+ The brief's `.bak` copy and `.brief-draft.json` sit beside it, and a stack group also holds `create-stack-skill-result-latest.json`. Names holding `.skf-` (locks such as `.skf-update.lock`, update-skill's `.skf-update-manual-inventory.json` beside it, and staging) and a stack's `*-tmp` staging folders are SKF's too; while a rename runs, its lock is `{forge_data_folder}/.skf-rename-{skill-name}.lock`. `_campaign/` and `improvement-queue/` are SKF's own folders, never a skill's. Older skills may still hold the provenance map, evidence report, extraction rules and test reports directly in `{skill-name}/` (the flat layout — see Migration), and a `.manual-inventory.json` in a version folder, where update-skill once kept the [MANUAL] inventory it now keeps beside its lock.
117
+
102
118
  ## Version Resolution
103
119
 
104
120
  ### Writing Workflows (CS, QS, SS, US)
105
121
 
106
122
  When writing artifacts, resolve `{version}` from the skill brief's `version` field (CS, SS), the extraction inventory (QS), or the updated metadata (US). Then:
107
123
 
124
+ 0. **Ownership check (CS, QS, SS).** Before creating anything, run `uv run skf-skill-inventory.py {skills_output_folder} --skill {skill-name} --write-check --write-version {version} --forge-data-folder {forge_data_folder}` and continue only when `write_check.verdict` is `"ok"`; otherwise stop with that verdict as the halt reason (`not-skf-output` or `flat-layout`). Without the helper, write only when nothing exists at `{skill_group}`. See Ownership below.
108
125
  1. Create `{skill_group}` if it does not exist
109
126
  2. Create `{skill_package}` (including all parent directories)
110
127
  3. Write all deliverables to `{skill_package}`
@@ -112,17 +129,23 @@ When writing artifacts, resolve `{version}` from the skill brief's `version` fie
112
129
  5. Write all workspace artifacts to `{forge_version}`
113
130
  6. Create or update the `active` symlink at `{skill_group}/active` pointing to `{version}`
114
131
 
115
- ### Reading Workflows (EX, AS, TS, VS, RA)
132
+ **Update-skill (US)** writes each new version into a folder of its own and never into the previous one. Before it writes the merged `SKILL.md`, it stages a copy of the current package with `skf-atomic-write.py stage-dir`, renames it into `{skill_group}/{new_version}/{skill-name}/` with `commit-dir`, creates `{forge_data_folder}/{skill-name}/{new_version}/` with copies of the provenance map, evidence report and extraction rules, and writes every artifact of the update there. It stops (`halted-for-write-failure`) rather than overwrite a version folder that already exists. `{new_version}` is the source's version when the update detected a higher one, else the next patch version. It updates the version the `active` link names when the manifest lags it (the Manifest-lag guard under Reading Workflows), so a second update before an export builds on the first. A gap-driven repair (`--from-test-report`) keeps its version and writes in place; `--detect-only` and `--dry-run` create nothing.
133
+
134
+ ### Reading Workflows (EX, AS, TS)
116
135
 
117
136
  When reading artifacts, resolve the skill path using the export manifest:
118
137
 
119
138
  1. Read `{skills_output_folder}/.export-manifest.json`
120
139
  2. Look up the skill name in `exports`
121
140
  3. Read `active_version` to get the target version
122
- 4. **Manifest-lag guard.** If the `active` symlink at `{skill_group}/active` resolves to a *different* version than the manifest's `active_version`, prefer the **symlink target** and emit an Info note. The manifest `active_version` only advances when `export-skill` runs, but the `active` symlink is flipped forward by every writing workflow (CS/QS/SS/US) the instant it commits a new version. So in the canonical SS→TS→EX order the manifest lags the just-forged version in the window between forge and export — a manifest-first read would otherwise resolve the *previously exported* version. Preferring the symlink target closes this gap (and, for `export-skill`, makes that export publish the forged version and reconcile the manifest). This guard never overrides legitimate state: `drop-skill` — the only workflow that switches the active version — repoints the symlink to the manifest's `active_version` (it never leaves them diverged), and no workflow flips the symlink *backward*, so the only divergence that can occur is exactly this forge→export lag.
141
+ 4. **Manifest-lag guard.** If the `active` symlink at `{skill_group}/active` resolves to a *different* version than the manifest's `active_version`, prefer the **symlink target** and emit an Info note. The manifest `active_version` only advances when `export-skill` runs, but the `active` symlink is flipped forward by every writing workflow (CS/QS/SS/US) the instant it commits a new version. So in the canonical SS→TS→EX order the manifest lags the just-forged version in the window between forge and export: a manifest-first read would otherwise resolve the *previously exported* version. Preferring the symlink target closes this gap (and, for `export-skill`, makes that export publish the forged version and reconcile the manifest). This guard never overrides legitimate state: `drop-skill`, the only workflow that switches the active version, repoints the symlink to the manifest's `active_version` (it never leaves them diverged), and no workflow flips the symlink *backward*. So the only other divergence is a backward flip the user makes by hand to keep an older version, as the drop guard's recovery asks (see Drop below): the next `export-skill` run then publishes that version, which is what the user asked for.
123
142
  5. Resolve to `{skill_package}` using the chosen version — the symlink target when it diverges per step 4, otherwise `active_version`
124
143
  6. If manifest does not contain the skill: check for `active` symlink at `{skill_group}/active`
125
- 7. If neither manifest nor symlink: fall back to flat-path resolution (migration — see below)
144
+ 7. If neither manifest nor symlink: fall back to flat-path resolution, only behind the ownership gate (see Ownership and Migration below)
145
+
146
+ **The resolve command.** A workflow never applies these steps by hand: `uv run skf-skill-inventory.py resolve {skills_output_folder} --skill {skill-name} --forge-data-folder {forge_data_folder}` applies them in one call (audit-skill, test-skill and export-skill choose their version with it, and drop-skill and rename-skill read their version lists from it). It returns the manifest's `active_version`, the `active` link's target (`symlink_target`), the `chosen_version` and its `reason` (`manifest-and-link`, `manifest`, `link`, `manifest-lags-link` for the guard in step 4, `flat-layout` for step 7, `newest-on-disk`, which a reading workflow does not audit or test, or `missing`), the `candidates` it compared (each version's package and provenance map, with the map's `generated_at`), `forge_version`, the `metadata.json`, `provenance-map.json` and `evidence-report.md` paths (`paths`, each the versioned file when it exists, else the flat one, else null), and every version newest first with its manifest status (`versions`, `counts`, `newest_non_deprecated`). `--version <version>` names the version instead, for an operator's choice (its `reason` is `requested`). It reads and never writes, and does not decide ownership (see Ownership).
147
+
148
+ **Stack rosters (VS, RA, SS compose-mode)** read through `skf-enumerate-stack-skills.py` instead: for each skill folder it takes the version the `active` link names, else the highest version, else a flat root `SKILL.md`. Only a package whose `metadata.json` carries an SKF marker counts (see Ownership). Its `enumerate` command never reads the export manifest; `candidates`, which picks create-stack-skill's compose-mode constituents, reads the manifest only to pick them, and the package of each one it keeps still comes from the roster.
126
149
 
127
150
  ### Manifest-Driven Snippet Scanning (EX Step-04)
128
151
 
@@ -169,6 +192,53 @@ The export manifest gains version awareness:
169
192
 
170
193
  **Only one version per skill can have `status: "active"` at any time.**
171
194
 
195
+ ## Ownership
196
+
197
+ The skills folder can hold skills SKF did not generate, such as a BMad module's own skills or skills installed from elsewhere. Before a workflow writes a new version into, moves or deletes a skill's folders, it asks `skf-skill-inventory.py` whether SKF generated them; it never decides by hand.
198
+
199
+ **Marker rules.** Only a `metadata.json` that carries an SKF marker proves that SKF generated a skill. Any one of these is a marker:
200
+
201
+ 1. `generated_by` is `quick-skill`, `create-skill` or `create-stack-skill`
202
+ 2. `tool_versions` is an object with an `skf` key
203
+ 3. `skill_type` is `single`, `individual` or `stack`, together with `forge_tier` or `confidence_tier`
204
+
205
+ Every SKF writer has written at least one of them since the first release. The marker counts at the group root (flat layout) or at `{skill_group}/{version}/{skill-name}/metadata.json` (versioned layout). The versioned layout, an `active` link, a manifest key or a result file do not count on their own. Setup's ccc exclusions use the same rule, so ccc leaves out exactly the skill folders the workflows treat as SKF output.
206
+
207
+ **Verdicts.** The inventory adds these fields to each skill:
208
+
209
+ | Field | Meaning |
210
+ |---|---|
211
+ | `ownership` | `"skf"`: SKF evidence and nothing else in the folder or its marked version folders. `"mixed"`: SKF evidence plus entries SKF did not generate. `"foreign"`: no SKF evidence, or the folder is a link |
212
+ | `skf_skill` | A marked version, or a flat skill with a marked root `metadata.json` |
213
+ | `flat_skf` | A root `SKILL.md` beside a marked root `metadata.json` |
214
+ | `foreign_entries` | The entries SKF did not generate; directories end in `/`, a link is listed by its bare name, and an entry inside a marked version folder is listed as `{version}/<entry>` |
215
+
216
+ SKF evidence is a marked version, a marked root `metadata.json`, the `_batch` folder, or `.skf-` in the folder name. A version folder that is a link, or that holds its package through a link, is never SKF output: SKF only creates the `active` link. A marked version folder holds only the `{skill-name}/` package and `.skf-` staging names; anything else in it is an entry SKF did not generate. The top-level `not_skf_output` names the folders that hold a skill SKF did not generate. `not_skf_output` never lists `_batch` or a `.skf-` name.
217
+
218
+ A folder that holds no file (only neutral clutter, `.skf-` names or empty folders), which is what an interrupted run leaves before it writes `metadata.json`, is never an entry SKF did not generate.
219
+
220
+ **Forge folders.** With `--forge-data-folder`, the inventory also classifies `{forge_data_folder}/{skill-name}` for each skill it scans, in the top-level `forge_groups[]` (`name`, `path`, `ownership`, `foreign_entries`, `errors`). The forge folder has no marker file, so SKF evidence there is its own files: a brief (`skill-brief.yaml*`, `.brief-draft.json`) or a `*-result*.json` directly in the folder, or a provenance map, evidence report, extraction rules or `*-result*.json` file in a folder directly inside it; a linked folder never holds any. The other names SKF writes (the forge tree above) count only beside that evidence. Setup's ccc exclusions use the same evidence rule for the forge folder.
221
+
222
+ | `ownership` | Meaning |
223
+ |---|---|
224
+ | `"absent"` | Nothing at the path |
225
+ | `"skf"` | SKF evidence and nothing else |
226
+ | `"mixed"` | SKF evidence plus entries SKF did not write, in `foreign_entries` (a folder SKF wrote nothing in as `{version}/`, an entry inside a marked one as `{version}/<entry>`) |
227
+ | `"empty"` | No evidence and nothing SKF did not write: an empty folder, or only locks and staging |
228
+ | `"foreign"` | Entries SKF did not write and no evidence, or the path is a link, is not a folder, or SKF cannot list it (`errors` says which) |
229
+ | `"reserved"` | `improvement-queue` or `_campaign`: SKF's own folder, never a skill's |
230
+
231
+ When both settings name one folder, the result has `same_folder: true` and an empty `forge_groups`: each skill folder is classified once, and an entry either rule accepts is SKF output, as setup's ccc exclusions do; only the skill's own `{version}/{skill-name}/` package still needs its SKF marker.
232
+
233
+ **How workflows use it:**
234
+
235
+ - US, AS, TS and EX migrate a flat skill only when `flat_skf` is true; otherwise they stop with `not-skf-output` before anything moves (see Migration below).
236
+ - CS, QS and SS write a version only after `--write-check` returns `"ok"`: nothing is at the skill folder yet, it holds only what an interrupted run leaves, or SKF generated it and the target version folder is new or SKF's own. They stop with `not-skf-output` for a folder SKF did not generate (a link included) or a version folder SKF did not generate, and with `flat-layout` for an SKF skill still only in the flat layout. The name `improvement-queue` is refused.
237
+ - RS renames only an `"skf"` folder in the versioned layout; it refuses others with `not-skf-output` or `flat-layout`. It moves the forge folder only when it is `"skf"` or `"empty"`, refuses (`not-skf-output`) one that is `"mixed"`, or `"foreign"` with `errors` because it is a link, is not a folder, or cannot be listed, and leaves any other `"foreign"` or `"reserved"` one under the old name.
238
+ - DS offers a folder SKF did not generate only when the manifest lists it, and then only for deprecate. It purges a whole skill folder only when its `ownership` is `"skf"` (or nothing is on disk). Its forge folder is purged when `"skf"` or `"empty"`, refused when `"mixed"`, and left in place when `"foreign"` or `"reserved"`; a single-version purge applies the same test to `{version}/` in the forge folder.
239
+ - VS, RA and SS compose-mode read only the skills SKF generated: `skf-enumerate-stack-skills.py` applies the same marker rule, lists the other skill folders once in `not_skf_output`, and never counts them as warnings or pairs; a folder whose `metadata.json` it cannot read is named in one warning instead, because it cannot tell whether SKF generated it. TS's discovery catalog counts the folders that hold a skill.
240
+ - Without the inventory helper, none of them moves or deletes a folder, and a writer writes only into a skill folder that does not exist yet.
241
+
172
242
  ## Skill Management Operations
173
243
 
174
244
  Two workflows operate on the version-aware structure for skill lifecycle management:
@@ -179,14 +249,14 @@ Renames a skill across all versions. Because the agentskills.io spec requires `n
179
249
  1. Outer `{skill_group}` directory: `{skills_output_folder}/{old-name}/` → `{skills_output_folder}/{new-name}/`
180
250
  2. Inner `{skill-name}/` directories inside each version: `{version}/{old-name}/` → `{version}/{new-name}/`
181
251
  3. `SKILL.md` frontmatter `name:` field (in every version)
182
- 4. `metadata.json` `name` field (in every version)
183
- 5. `context-snippet.md` root paths and display name (in every version)
184
- 6. `provenance-map.json` `skill_name` field (in every version under `{forge_group}`)
185
- 7. `{forge_group}` directory: `{forge_data_folder}/{old-name}/` → `{forge_data_folder}/{new-name}/`
252
+ 4. `metadata.json` `name` field, and any path value into a moved folder, such as a recorded test report path (in every version)
253
+ 5. The name where the snippet template writes it in `context-snippet.md`: display header, first word and `writing {name} code` on the `|IMPORTANT:` line, and root paths (in every version). A field label, a fixed template word or library content that is the old name stays, and the no-trace check then rolls the rename back
254
+ 6. `provenance-map.json` `skill_name` field, and any path value into a moved folder (in every version under `{forge_group}`)
255
+ 7. `{forge_group}` directory: `{forge_data_folder}/{old-name}/` → `{forge_data_folder}/{new-name}/`, only when SKF generated it (see Ownership; a forge folder SKF did not generate keeps the old name)
186
256
  8. Export manifest: remove old key, add new key with same version data
187
257
  9. Platform context files (CLAUDE.md, AGENTS.md, .cursorrules): rebuild managed sections
188
258
 
189
- Rename is transactional — copy-verify-delete pattern. If any step fails, old skill remains intact. See `skf-rename-skill/`.
259
+ Rename is transactional — copy-verify-delete pattern. If any step fails, old skill remains intact. The verify step is the no-trace check: before anything is deleted, it looks for the old name as a whole name in each version's `SKILL.md` frontmatter, `metadata.json`, `context-snippet.md` and `provenance-map.json`, and rolls the rename back on a match. In the two JSON files it skips the values of the keys that name the upstream source, `source_repo`, `source_root`, `source_commit`, `source_ref`, `source_package` and `source_library`: they describe the source the skill was made from, not the skill, and a rename leaves them unchanged. Because it moves the whole `{skill_group}`, rename refuses a folder SKF did not generate or one that also holds entries SKF did not generate (`not-skf-output`), and a skill still in the flat layout (`flat-layout`) — see Ownership. It also refuses a forge folder that holds entries SKF did not write, or that is a link, is not a folder, or cannot be listed. See `skf-rename-skill/`.
190
260
 
191
261
  ### Drop (DS - Drop Skill)
192
262
 
@@ -194,11 +264,13 @@ Drops a specific version or the entire skill with two modes:
194
264
 
195
265
  **Soft drop (default):** Sets version status to `"deprecated"` in the export manifest. Files remain on disk. Export-skill excludes deprecated versions from all platform context files. Reversible by manually editing manifest back to `"active"`/`"archived"`.
196
266
 
197
- **Hard drop (`--purge`):** Same as soft drop, plus deletes the version directory (`{skill_package}`) and forge data directory (`{forge_version}`). Irreversible.
267
+ **Hard drop (`--purge`):** Same as soft drop, plus deletes the version directory (`{skill_package}`) and forge data directory (`{forge_version}`, only when SKF generated it). Irreversible.
268
+
269
+ **Active version guard:** Cannot drop the active version while other non-deprecated versions exist. The user must either make the version they keep active first (point the `active` link at it with `ln -sfn <version to keep> {skill_group}/active`, then run export-skill: the Manifest-lag guard makes it export that version, and its manifest update archives the old one), or drop all versions at once.
198
270
 
199
- **Active version guard:** Cannot drop the active version when other versions exist. The user must either switch active to another version first, or drop all versions at once.
271
+ **Skill-level drop:** Removes the entire `{skill_group}` from the manifest. If purge, also deletes `{skill_group}` and `{forge_group}` directories (the forge one only when SKF generated it).
200
272
 
201
- **Skill-level drop:** Removes the entire `{skill_group}` from the manifest. If purge, also deletes `{skill_group}` and `{forge_group}` directories.
273
+ **Ownership guard:** A purge deletes only SKF output. A whole-skill purge needs `ownership` `"skf"` (or nothing on disk); a `"mixed"` folder allows only a single-version purge of a marked version that is not a link and holds nothing SKF did not generate, and a `"foreign"` folder no purge at all (`not-skf-output`). A folder SKF did not generate is offered only when the manifest lists it, and then only for deprecate. The forge folder follows the same test: a whole-skill purge is refused when it is `"mixed"` and leaves it in place when SKF did not generate it; a single-version purge leaves a forge `{version}/` SKF did not generate in place and refuses one that holds entries SKF did not write.
202
274
 
203
275
  See `skf-drop-skill/`.
204
276
 
@@ -215,13 +287,26 @@ Directory names use the semver version with `+{build}` metadata stripped:
215
287
 
216
288
  Build metadata does not affect version precedence per the semver specification and is stripped to avoid filesystem issues with the `+` character.
217
289
 
290
+ ### Version Commands
291
+
292
+ Comparing, bumping and naming versions has one answer, so no workflow does it by eye: `skf-skill-inventory.py version` does.
293
+
294
+ | Command | Answer | Used by |
295
+ |---------|--------|---------|
296
+ | `version normalize <version>` | the folder name of a version or a range by the rules above (`^18.2.0` gives `18.2.0`, build metadata stripped) | the other commands, on what they return; call it alone for a version string from elsewhere |
297
+ | `version order <a> <b>` | which of two versions is higher (`1.10.0` above `1.9.0`) | update-skill, whether the source's version is above the skill's |
298
+ | `version next-patch <version>` | the next patch version (a pre-release gives its release) | update-skill's new version folder |
299
+ | `version bump --prior <v> --prior-libraries <a,b> --libraries <a,c>` | a compose-mode stack's next version: major when a library was removed, else minor, refused (`NOT_INCREASING`) when not above the prior one | create-stack-skill |
300
+ | `version primary <candidates.json or ->` | a code-mode stack's primary library and the version it gives, ties broken by a fixed rule | create-stack-skill |
301
+
218
302
  ## Migration: Flat to Versioned
219
303
 
220
- When a reading workflow encounters a skill at the flat path (`{skills_output_folder}/{skill-name}/SKILL.md` exists directly — no version subdirectory), it auto-migrates:
304
+ When US, AS, TS or EX encounters a skill at the flat path (`{skills_output_folder}/{skill-name}/SKILL.md` exists directly — no version subdirectory), it auto-migrates:
221
305
 
222
- 1. Read `metadata.json` from the flat path to get the `version` field
306
+ 0. **Ownership gate.** Run `uv run skf-skill-inventory.py {skills_output_folder} --skill {skill-name}` and migrate only when `skills[0].flat_skf` is true: the root `metadata.json` carries an SKF marker (`generated_by`, `tool_versions.skf`, or `skill_type` with `forge_tier` or `confidence_tier` — see Ownership). Otherwise, or when the helper is missing, stop with `not-skf-output` before anything moves. The message says a shared skills folder is supported and SKF leaves the skills it did not generate alone, so the user manages that skill; it points to `skills_output_folder` in `{project-root}/_bmad/skf/config.yaml` only for a folder that holds a module's own source. Read-only modes never migrate. Export-skill `--dry-run` reads the flat package in place. Update-skill `--dry-run` and `--detect-only` stop instead (`blocked`, phase `init:read-only-flat-layout`), because its later steps need the versioned forge workspace: run US, AS, TS or EX once without a read-only flag to migrate, then re-run.
307
+ 1. Read `metadata.json` from the flat path to get the `version` field. If it has none, use `1.0.0`. Either way, name the directory by the Version Sanitization rules above
223
308
  2. Create the versioned directory: `{skill_group}/{version}/{skill-name}/`
224
- 3. Move all package files (SKILL.md, metadata.json, context-snippet.md, references/, scripts/, assets/) into the versioned location
309
+ 3. Move the package files (SKILL.md, metadata.json, context-snippet.md, references/, scripts/, assets/) into the versioned location. Any other entry in the folder stays where it is
225
310
  4. Create the `active` symlink: `{skill_group}/active -> {version}`
226
311
  5. If `{forge_data_folder}/{skill-name}/` contains provenance artifacts at the flat level (not in a version subdirectory):
227
312
  - Create `{forge_version}`
@@ -241,6 +326,7 @@ When a reading workflow encounters a skill at the flat path (`{skills_output_fol
241
326
  - Versioning platform root paths — platform paths stay flat, version lives in the forge workspace
242
327
  - Using glob patterns to discover snippets across all versions — use the export manifest to resolve the active version
243
328
  - Creating version directories with `+` in the name — strip build metadata
329
+ - Writing into, migrating, renaming or purging a skill folder without the ownership check — a folder in `{skills_output_folder}` is SKF output only when a `metadata.json` in it carries an SKF marker, and a folder in `{forge_data_folder}` only when it holds SKF's brief, a result file, or a version folder with a provenance map, evidence report or extraction rules file
244
330
 
245
331
  ## Related Fragments
246
332
 
@@ -9,10 +9,10 @@ skf,skf-quick-skill,Quick Skill,QS,"Fast skill from a package name or GitHub URL
9
9
  skf,skf-create-stack-skill,Stack Skill,SS,"Consolidated project stack skill with integration patterns — code-mode or compose-mode",,,anytime,skf-create-skill,skf-test-skill,false,skills_output_folder,SKILL.md
10
10
  skf,skf-update-skill,Update Skill,US,"Smart regeneration preserving [MANUAL] sections after source changes",,,anytime,skf-export-skill,,false,skills_output_folder,SKILL.md
11
11
  skf,skf-audit-skill,Audit Skill,AS,"Drift detection between skill and current source code",,,anytime,skf-export-skill,,false,,drift report
12
- skf,skf-verify-stack,Verify Stack,VS,"Pre-code stack feasibility verification against architecture and PRD documents",,,anytime,skf-setup,skf-refine-architecture,false,forge_data_folder,feasibility-report-{project_name}.md
13
- skf,skf-refine-architecture,Refine Architecture,RA,"Improve architecture doc using verified skill data and VS feasibility findings",,,anytime,skf-verify-stack,,false,output_folder,refined-architecture-{arch_project_name}.md
12
+ skf,skf-verify-stack,Verify Stack,VS,"Pre-code stack feasibility verification against architecture and PRD documents",,,anytime,skf-setup,skf-refine-architecture,false,forge_data_folder,feasibility-report-{project_slug}-latest.md
13
+ skf,skf-refine-architecture,Refine Architecture,RA,"Refine an architecture document against generated skills and a Verify Stack report",,,anytime,skf-verify-stack,,false,output_folder,refined-architecture-{arch_project_name}.md
14
14
  skf,skf-test-skill,Test Skill,TS,"Cognitive completeness verification — quality gate before export",,,anytime,"skf-create-skill,skf-create-stack-skill,skf-quick-skill",skf-export-skill,false,,completeness score
15
- skf,skf-export-skill,Export Skill,EX,"Package for distribution and inject context into CLAUDE.md/AGENTS.md/.cursorrules",,,anytime,skf-test-skill,"skf-update-skill,skf-audit-skill,skf-rename-skill,skf-drop-skill",false,skills_output_folder,agentskills.io package
15
+ skf,skf-export-skill,Export Skill,EX,"Validate a skill's package, write its context snippet and update the managed section in CLAUDE.md, AGENTS.md or .cursorrules",,,anytime,skf-test-skill,"skf-update-skill,skf-audit-skill,skf-rename-skill,skf-drop-skill",false,skills_output_folder,agentskills.io package
16
16
  skf,skf-rename-skill,Rename Skill,RS,"Rename a skill across all its versions — transactional copy-verify-delete with platform context rebuild",,,anytime,skf-export-skill,,false,skills_output_folder,renamed skill group
17
17
  skf,skf-drop-skill,Drop Skill,DS,"Drop a specific skill version or an entire skill — soft (deprecate) or hard (purge) with platform context rebuild",,,anytime,skf-export-skill,,false,skills_output_folder,updated manifest
18
18
  skf,skf-forger,Knowledge Index,KI,"Cross-cutting principles and patterns — JiT loaded by workflows via index lookup",,,anytime,,,false,,knowledge fragments
package/src/module.yaml CHANGED
@@ -24,6 +24,16 @@ health_check_repo:
24
24
  prompt: false
25
25
  default: "armelhbobdad/bmad-module-skill-forge"
26
26
 
27
+ # The agent roster: a BMAD Method install writes each entry to
28
+ # {project-root}/_bmad/config.toml as [agents.<code>]. The entry mirrors the
29
+ # [agent] block of skf-forger/customize.toml.
30
+ agents:
31
+ - code: skf-forger
32
+ name: Ferris
33
+ title: "Skill Architect & Integrity Guardian"
34
+ icon: "⚒️"
35
+ description: "Skill compilation specialist who transforms code repositories, documentation, and developer discourse into verified agent skills."
36
+
27
37
  # Variables from Core Config inserted:
28
38
  ## user_name
29
39
  ## communication_language