bmad-module-skill-forge 2.2.0 → 4.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 (437) 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 +143 -18
  18. package/docs/verifying-a-skill.md +87 -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 +3 -3
  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 +31 -59
  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 +233 -64
  64. package/src/shared/scripts/skf-build-change-manifest.py +2753 -28
  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 +772 -0
  69. package/src/shared/scripts/skf-comention-pairs.py +1333 -123
  70. package/src/shared/scripts/skf-compare-file-hashes.py +267 -105
  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 +21 -3
  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 +197 -55
  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 +5247 -96
  86. package/src/shared/scripts/skf-extraction-inventory.py +1280 -0
  87. package/src/shared/scripts/skf-extraction-snapshot.py +664 -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 +469 -205
  92. package/src/shared/scripts/skf-github-fetch.py +365 -0
  93. package/src/shared/scripts/skf-github-probe.py +700 -0
  94. package/src/shared/scripts/skf-hash-content.py +180 -20
  95. package/src/shared/scripts/skf-language-corpora.py +1 -1
  96. package/src/shared/scripts/skf-load-provenance.py +161 -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 +143 -20
  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 +176 -28
  105. package/src/shared/scripts/skf-promote-staged.py +430 -0
  106. package/src/shared/scripts/skf-provenance-gap-dispatch.py +64 -8
  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 +155 -14
  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 +787 -121
  127. package/src/shared/scripts/skf-tessl-review.py +706 -0
  128. package/src/shared/scripts/skf-update-active-symlink.py +120 -67
  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 +23 -2
  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 +3945 -152
  138. package/src/shared/scripts/skf-write-skill-brief.py +406 -25
  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 +28 -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/health-check.md +2 -0
  168. package/src/skf-audit-skill/references/init.md +149 -210
  169. package/src/skf-audit-skill/references/re-index.md +103 -110
  170. package/src/skf-audit-skill/references/report.md +96 -33
  171. package/src/skf-audit-skill/references/semantic-diff.md +34 -25
  172. package/src/skf-audit-skill/references/severity-classify.md +79 -65
  173. package/src/skf-audit-skill/references/severity-rules.md +15 -6
  174. package/src/skf-audit-skill/references/structural-diff.md +80 -90
  175. package/src/skf-audit-skill/references/upstream-checkout.md +77 -0
  176. package/src/skf-audit-skill/scripts/render-drift-tables.py +712 -0
  177. package/src/skf-brief-skill/SKILL.md +37 -26
  178. package/src/skf-brief-skill/assets/description-voice-examples.md +1 -1
  179. package/src/skf-brief-skill/assets/scope-templates.md +18 -25
  180. package/src/skf-brief-skill/assets/skill-brief-schema.md +30 -23
  181. package/src/skf-brief-skill/customize.toml +48 -20
  182. package/src/skf-brief-skill/references/analyze-target.md +144 -127
  183. package/src/skf-brief-skill/references/confirm-brief.md +11 -9
  184. package/src/skf-brief-skill/references/draft-checkpoint.md +36 -17
  185. package/src/skf-brief-skill/references/gather-intent-ratify.md +68 -0
  186. package/src/skf-brief-skill/references/gather-intent.md +87 -182
  187. package/src/skf-brief-skill/references/headless-args.md +84 -16
  188. package/src/skf-brief-skill/references/health-check.md +1 -1
  189. package/src/skf-brief-skill/references/invocation-contract.md +18 -13
  190. package/src/skf-brief-skill/references/portfolio-similarity-check.md +1 -1
  191. package/src/skf-brief-skill/references/qmd-collection-registration.md +7 -10
  192. package/src/skf-brief-skill/references/scope-definition.md +123 -47
  193. package/src/skf-brief-skill/references/step-auto-brief.md +26 -100
  194. package/src/skf-brief-skill/references/step-auto-validate.md +20 -121
  195. package/src/skf-brief-skill/references/version-resolution.md +7 -10
  196. package/src/skf-brief-skill/references/write-brief.md +66 -57
  197. package/src/skf-campaign/SKILL.md +31 -34
  198. package/src/skf-campaign/assets/campaign-state-schema.json +25 -4
  199. package/src/skf-campaign/customize.toml +47 -16
  200. package/src/skf-campaign/references/campaign-contracts.md +39 -29
  201. package/src/skf-campaign/references/campaign-directive-spec.md +4 -2
  202. package/src/skf-campaign/references/health-check.md +7 -16
  203. package/src/skf-campaign/references/step-01-setup.md +46 -84
  204. package/src/skf-campaign/references/step-02-strategy.md +31 -30
  205. package/src/skf-campaign/references/step-03-pins.md +26 -18
  206. package/src/skf-campaign/references/step-04-provenance.md +24 -23
  207. package/src/skf-campaign/references/step-05-skill-loop.md +67 -48
  208. package/src/skf-campaign/references/step-06-batch.md +41 -34
  209. package/src/skf-campaign/references/step-07-capstone.md +40 -25
  210. package/src/skf-campaign/references/step-08-verify.md +28 -29
  211. package/src/skf-campaign/references/step-09-refine.md +29 -30
  212. package/src/skf-campaign/references/step-10-export.md +48 -36
  213. package/src/skf-campaign/references/step-11-maintenance.md +31 -34
  214. package/src/skf-campaign/references/step-resume.md +37 -68
  215. package/src/skf-campaign/scripts/campaign-deps.py +57 -18
  216. package/src/skf-campaign/scripts/campaign-parse-manifest.py +361 -54
  217. package/src/skf-campaign/scripts/campaign-provenance.py +96 -53
  218. package/src/skf-campaign/scripts/campaign-quality-gate.py +592 -0
  219. package/src/skf-campaign/scripts/campaign-render-batch.py +257 -49
  220. package/src/skf-campaign/scripts/campaign-render-kickoff.py +343 -50
  221. package/src/skf-campaign/scripts/campaign-report.py +204 -37
  222. package/src/skf-campaign/scripts/campaign-state.py +1128 -0
  223. package/src/skf-campaign/scripts/campaign-status.py +10 -74
  224. package/src/skf-campaign/scripts/campaign-validate-pins.py +30 -3
  225. package/src/skf-campaign/scripts/campaign-validate-state.py +34 -4
  226. package/src/skf-campaign/templates/campaign-brief-template.yaml +4 -5
  227. package/src/skf-campaign/templates/campaign-report-template.md +5 -1
  228. package/src/skf-campaign/templates/kickoff-template.md +0 -14
  229. package/src/skf-create-skill/SKILL.md +27 -20
  230. package/src/skf-create-skill/assets/compile-assembly-rules.md +11 -8
  231. package/src/skf-create-skill/assets/skill-sections.md +21 -11
  232. package/src/skf-create-skill/customize.toml +20 -8
  233. package/src/skf-create-skill/references/authoritative-files-protocol.md +36 -58
  234. package/src/skf-create-skill/references/batch-mode.md +81 -0
  235. package/src/skf-create-skill/references/ccc-index-check.md +27 -0
  236. package/src/skf-create-skill/references/compile.md +119 -70
  237. package/src/skf-create-skill/references/component-extraction.md +113 -91
  238. package/src/skf-create-skill/references/enrich.md +41 -23
  239. package/src/skf-create-skill/references/entry-points-by-hand.md +37 -0
  240. package/src/skf-create-skill/references/extract.md +204 -162
  241. package/src/skf-create-skill/references/extraction-patterns-by-hand.md +141 -0
  242. package/src/skf-create-skill/references/extraction-patterns-tracing.md +11 -11
  243. package/src/skf-create-skill/references/extraction-patterns.md +588 -201
  244. package/src/skf-create-skill/references/generate-artifacts.md +145 -93
  245. package/src/skf-create-skill/references/health-check.md +1 -1
  246. package/src/skf-create-skill/references/load-brief.md +53 -36
  247. package/src/skf-create-skill/references/relabel-rule.md +12 -0
  248. package/src/skf-create-skill/references/report.md +37 -57
  249. package/src/skf-create-skill/references/source-resolution-protocols.md +58 -169
  250. package/src/skf-create-skill/references/step-auto-shard.md +20 -93
  251. package/src/skf-create-skill/references/step-doc-rot.md +44 -60
  252. package/src/skf-create-skill/references/step-doc-sources.md +28 -19
  253. package/src/skf-create-skill/references/sub/ccc-discover.md +18 -7
  254. package/src/skf-create-skill/references/sub/fetch-docs.md +106 -59
  255. package/src/skf-create-skill/references/sub/fetch-temporal.md +53 -166
  256. package/src/skf-create-skill/references/tier-degradation-rules.md +18 -9
  257. package/src/skf-create-skill/references/validate.md +173 -99
  258. package/src/skf-create-skill/scripts/scan-doc-rot.py +232 -99
  259. package/src/skf-create-stack-skill/SKILL.md +29 -56
  260. package/src/skf-create-stack-skill/assets/metadata-contract.md +51 -0
  261. package/src/skf-create-stack-skill/assets/provenance-map-schema.md +15 -15
  262. package/src/skf-create-stack-skill/assets/stack-skill-template.md +23 -57
  263. package/src/skf-create-stack-skill/customize.toml +23 -12
  264. package/src/skf-create-stack-skill/references/compile-stack.md +57 -66
  265. package/src/skf-create-stack-skill/references/compose-mode-rules.md +24 -44
  266. package/src/skf-create-stack-skill/references/detect-integrations.md +92 -95
  267. package/src/skf-create-stack-skill/references/detect-manifests.md +46 -71
  268. package/src/skf-create-stack-skill/references/generate-output.md +138 -128
  269. package/src/skf-create-stack-skill/references/init.md +90 -32
  270. package/src/skf-create-stack-skill/references/integration-patterns.md +1 -17
  271. package/src/skf-create-stack-skill/references/invocation-contract.md +34 -0
  272. package/src/skf-create-stack-skill/references/manifest-patterns.md +32 -20
  273. package/src/skf-create-stack-skill/references/parallel-extract.md +112 -38
  274. package/src/skf-create-stack-skill/references/rank-and-confirm.md +57 -75
  275. package/src/skf-create-stack-skill/references/report.md +39 -33
  276. package/src/skf-create-stack-skill/references/validate.md +20 -39
  277. package/src/skf-drop-skill/SKILL.md +28 -51
  278. package/src/skf-drop-skill/customize.toml +44 -30
  279. package/src/skf-drop-skill/references/execute.md +83 -146
  280. package/src/skf-drop-skill/references/health-check.md +2 -0
  281. package/src/skf-drop-skill/references/invocation-contract.md +64 -0
  282. package/src/skf-drop-skill/references/report.md +46 -30
  283. package/src/skf-drop-skill/references/select.md +122 -124
  284. package/src/skf-drop-skill/scripts/dir-sizes.py +54 -26
  285. package/src/skf-drop-skill/scripts/drop-roster.py +322 -0
  286. package/src/skf-export-skill/SKILL.md +40 -62
  287. package/src/skf-export-skill/assets/managed-section-format.md +14 -50
  288. package/src/skf-export-skill/assets/snippet-format.md +3 -1
  289. package/src/skf-export-skill/customize.toml +42 -13
  290. package/src/skf-export-skill/references/generate-snippet.md +54 -46
  291. package/src/skf-export-skill/references/health-check.md +2 -0
  292. package/src/skf-export-skill/references/invocation-contract.md +15 -0
  293. package/src/skf-export-skill/references/load-skill.md +88 -62
  294. package/src/skf-export-skill/references/manifest-rebuild.md +9 -10
  295. package/src/skf-export-skill/references/multi-skill-mode.md +4 -4
  296. package/src/skf-export-skill/references/orphan-context-detection.md +13 -5
  297. package/src/skf-export-skill/references/orphan-row-detection.md +31 -22
  298. package/src/skf-export-skill/references/package.md +15 -73
  299. package/src/skf-export-skill/references/preflight-snippet-root-probe.md +51 -70
  300. package/src/skf-export-skill/references/result-envelope.md +31 -16
  301. package/src/skf-export-skill/references/summary.md +41 -17
  302. package/src/skf-export-skill/references/token-report.md +4 -12
  303. package/src/skf-export-skill/references/update-context.md +118 -237
  304. package/src/skf-forger/SKILL.md +61 -37
  305. package/src/skf-forger/bmad-skill-manifest.yaml +4 -1
  306. package/src/skf-forger/customize.toml +43 -0
  307. package/src/skf-forger/references/pipeline-mode.md +73 -18
  308. package/src/skf-forger/scripts/forge-status.py +299 -0
  309. package/src/skf-forger/scripts/parse-pipeline.py +322 -54
  310. package/src/skf-forger/scripts/pipeline-gate.py +428 -0
  311. package/src/skf-forger/scripts/pipeline-journal.py +1052 -0
  312. package/src/skf-quick-skill/SKILL.md +54 -53
  313. package/src/skf-quick-skill/assets/skill-template.md +4 -2
  314. package/src/skf-quick-skill/customize.toml +51 -20
  315. package/src/skf-quick-skill/references/batch-mode.md +74 -21
  316. package/src/skf-quick-skill/references/compile.md +30 -31
  317. package/src/skf-quick-skill/references/ecosystem-check.md +7 -57
  318. package/src/skf-quick-skill/references/finalize.md +69 -18
  319. package/src/skf-quick-skill/references/halt-contract.md +41 -29
  320. package/src/skf-quick-skill/references/health-check.md +5 -3
  321. package/src/skf-quick-skill/references/quick-extract.md +114 -45
  322. package/src/skf-quick-skill/references/registry-resolution.md +9 -64
  323. package/src/skf-quick-skill/references/resolve-target.md +116 -66
  324. package/src/skf-quick-skill/references/write-and-validate.md +79 -40
  325. package/src/skf-refine-architecture/SKILL.md +43 -53
  326. package/src/skf-refine-architecture/customize.toml +49 -20
  327. package/src/skf-refine-architecture/references/compile.md +97 -54
  328. package/src/skf-refine-architecture/references/exit-codes.md +30 -0
  329. package/src/skf-refine-architecture/references/finding-storage.md +21 -0
  330. package/src/skf-refine-architecture/references/gap-analysis.md +101 -38
  331. package/src/skf-refine-architecture/references/improvements.md +14 -20
  332. package/src/skf-refine-architecture/references/init.md +98 -57
  333. package/src/skf-refine-architecture/references/issue-detection.md +32 -39
  334. package/src/skf-refine-architecture/references/refinement-rules.md +37 -48
  335. package/src/skf-refine-architecture/references/report.md +65 -54
  336. package/src/skf-refine-architecture/scripts/skf-check-preservation.py +1619 -0
  337. package/src/skf-rename-skill/SKILL.md +19 -54
  338. package/src/skf-rename-skill/customize.toml +32 -26
  339. package/src/skf-rename-skill/references/execute.md +230 -184
  340. package/src/skf-rename-skill/references/exit-codes.md +7 -7
  341. package/src/skf-rename-skill/references/health-check.md +1 -7
  342. package/src/skf-rename-skill/references/invocation-contract.md +25 -0
  343. package/src/skf-rename-skill/references/report.md +63 -52
  344. package/src/skf-rename-skill/references/select.md +197 -115
  345. package/src/skf-rename-skill/scripts/skf-validate-rename-name.py +161 -21
  346. package/src/skf-setup/SKILL.md +26 -26
  347. package/src/skf-setup/customize.toml +14 -10
  348. package/src/skf-setup/references/auto-index.md +50 -63
  349. package/src/skf-setup/references/ccc-index.md +29 -90
  350. package/src/skf-setup/references/detect-and-tier.md +58 -67
  351. package/src/skf-setup/references/health-check.md +2 -0
  352. package/src/skf-setup/references/invocation-contract.md +14 -0
  353. package/src/skf-setup/references/report.md +43 -166
  354. package/src/skf-setup/references/tier-rules.md +5 -5
  355. package/src/skf-setup/references/write-config.md +34 -57
  356. package/src/skf-test-skill/SKILL.md +17 -57
  357. package/src/skf-test-skill/assets/output-section-formats.md +33 -34
  358. package/src/skf-test-skill/customize.toml +27 -13
  359. package/src/skf-test-skill/references/coherence-check.md +134 -62
  360. package/src/skf-test-skill/references/coverage-check-tiers.md +35 -0
  361. package/src/skf-test-skill/references/coverage-check.md +209 -264
  362. package/src/skf-test-skill/references/detect-mode.md +5 -5
  363. package/src/skf-test-skill/references/external-validators.md +94 -82
  364. package/src/skf-test-skill/references/health-check.md +6 -7
  365. package/src/skf-test-skill/references/init.md +164 -91
  366. package/src/skf-test-skill/references/invocation-contract.md +66 -0
  367. package/src/skf-test-skill/references/migration-section-rules.md +5 -2
  368. package/src/skf-test-skill/references/report.md +164 -142
  369. package/src/skf-test-skill/references/score.md +80 -107
  370. package/src/skf-test-skill/references/scoring-rules.md +42 -155
  371. package/src/skf-test-skill/references/source-access-protocol.md +18 -94
  372. package/src/skf-test-skill/references/step-hard-gate.md +51 -33
  373. package/src/skf-test-skill/scripts/aggregate-coherence.py +218 -30
  374. package/src/skf-test-skill/scripts/build-result-context.py +380 -0
  375. package/src/skf-test-skill/scripts/check-metadata-coherence.py +37 -4
  376. package/src/skf-test-skill/scripts/combine-external-scores.py +23 -6
  377. package/src/skf-test-skill/scripts/compute-score.py +223 -45
  378. package/src/skf-test-skill/scripts/gap-ledger.py +1666 -0
  379. package/src/skf-test-skill/scripts/hard-gate.py +203 -0
  380. package/src/skf-test-skill/scripts/load-coverage-inputs.py +1198 -0
  381. package/src/skf-test-skill/scripts/locate-export-segments.py +835 -0
  382. package/src/skf-test-skill/scripts/reconcile-coverage.py +547 -79
  383. package/src/skf-test-skill/scripts/score-signatures.py +479 -0
  384. package/src/skf-test-skill/scripts/stage-helper-payload.py +148 -0
  385. package/src/skf-test-skill/scripts/validate-inventory.py +311 -16
  386. package/src/skf-test-skill/scripts/verify-declared-numerator.py +133 -56
  387. package/src/skf-test-skill/templates/test-report-template.md +21 -15
  388. package/src/skf-update-skill/SKILL.md +38 -25
  389. package/src/skf-update-skill/customize.toml +27 -12
  390. package/src/skf-update-skill/references/detect-changes.md +253 -223
  391. package/src/skf-update-skill/references/gap-driven.md +336 -0
  392. package/src/skf-update-skill/references/health-check.md +31 -5
  393. package/src/skf-update-skill/references/init.md +254 -84
  394. package/src/skf-update-skill/references/invocation-contract.md +12 -0
  395. package/src/skf-update-skill/references/manual-section-rules.md +6 -23
  396. package/src/skf-update-skill/references/merge.md +182 -49
  397. package/src/skf-update-skill/references/re-extract.md +53 -262
  398. package/src/skf-update-skill/references/report.md +102 -35
  399. package/src/skf-update-skill/references/write.md +357 -155
  400. package/src/skf-update-skill/scripts/skf-new-file-diff.py +183 -46
  401. package/src/skf-verify-stack/SKILL.md +23 -42
  402. package/src/skf-verify-stack/assets/feasibility-report-template.md +11 -5
  403. package/src/skf-verify-stack/customize.toml +55 -22
  404. package/src/skf-verify-stack/references/coverage-patterns.md +17 -8
  405. package/src/skf-verify-stack/references/coverage.md +67 -64
  406. package/src/skf-verify-stack/references/exit-codes.md +21 -8
  407. package/src/skf-verify-stack/references/init.md +107 -62
  408. package/src/skf-verify-stack/references/integration-verification-rules.md +12 -13
  409. package/src/skf-verify-stack/references/integrations.md +106 -65
  410. package/src/skf-verify-stack/references/report.md +59 -42
  411. package/src/skf-verify-stack/references/requirements.md +32 -9
  412. package/src/skf-verify-stack/references/synthesize.md +53 -39
  413. package/src/skf-verify-stack/scripts/skf-coverage-tally.py +398 -52
  414. package/src/skf-verify-stack/scripts/skf-previous-report.py +330 -0
  415. package/src/skf-verify-stack/scripts/skf-report-delta.py +453 -49
  416. package/src/skf-verify-stack/scripts/skf-verdict-rollup.py +240 -27
  417. package/tools/cli/commands/install.js +11 -4
  418. package/tools/cli/commands/status.js +15 -3
  419. package/tools/cli/commands/update.js +11 -4
  420. package/tools/cli/lib/tool-check.js +320 -0
  421. package/tools/cli/lib/version-check.js +22 -9
  422. package/tools/cli/skf-cli.js +4 -1
  423. package/.gitattributes +0 -16
  424. package/.nvmrc +0 -1
  425. package/docs/_internal/RELEASING.md +0 -679
  426. package/release-audits/v1.0.0-launch-audit.md +0 -728
  427. package/src/skf-audit-skill/references/step-doc-drift.md +0 -177
  428. package/src/skf-brief-skill/references/headless-source-authority-detection.md +0 -26
  429. package/src/skf-campaign/manifest.yaml +0 -15
  430. package/src/skf-create-skill/assets/tessl-dismissal-rules.md +0 -106
  431. package/src/skf-create-skill/references/ecosystem-check.md +0 -74
  432. package/src/skf-drop-skill/references/headless-contract.md +0 -18
  433. package/src/skf-update-skill/references/merge-conflict-rules.md +0 -15
  434. package/src/skf-update-skill/references/remote-source-resolution.md +0 -98
  435. package/src/skf-update-skill/references/validate.md +0 -124
  436. package/tools/validate-docs-drift.js +0 -233
  437. package/tools/validate-docs-links.js +0 -665
@@ -1,6 +1,18 @@
1
1
  ---
2
2
  nextStepFile: 'detect-manifests.md'
3
3
  forgeTierFile: '{sidecar_path}/forge-tier.yaml'
4
+ emitEnvelopeProbeOrder:
5
+ - '{project-root}/_bmad/skf/shared/scripts/skf-emit-result-envelope.py'
6
+ - '{project-root}/src/shared/scripts/skf-emit-result-envelope.py'
7
+ frontmatterValidatorProbeOrder:
8
+ - '{project-root}/_bmad/skf/shared/scripts/skf-validate-frontmatter.py'
9
+ - '{project-root}/src/shared/scripts/skf-validate-frontmatter.py'
10
+ scanManifestsProbeOrder:
11
+ - '{project-root}/_bmad/skf/shared/scripts/skf-scan-manifests.py'
12
+ - '{project-root}/src/shared/scripts/skf-scan-manifests.py'
13
+ enumerateStackSkillsProbeOrder:
14
+ - '{project-root}/_bmad/skf/shared/scripts/skf-enumerate-stack-skills.py'
15
+ - '{project-root}/src/shared/scripts/skf-enumerate-stack-skills.py'
4
16
  ---
5
17
 
6
18
  <!-- Config: communicate in {communication_language}. -->
@@ -9,17 +21,43 @@ forgeTierFile: '{sidecar_path}/forge-tier.yaml'
9
21
 
10
22
  ## STEP GOAL:
11
23
 
12
- Load forge tier configuration, validate prerequisites, and prepare the stack skill workflow for execution.
24
+ Load forge tier configuration, validate prerequisites, bind and check the invocation inputs, and choose the mode and the folder code mode scans.
13
25
 
14
26
  ## Rules
15
27
 
16
- - Focus only on loading configuration and validating prerequisites — do not start analyzing dependencies
28
+ - Focus on configuration, prerequisites, inputs and the mode: the two helper runs of §3 only decide the mode and the scan scope, and ranking dependencies is step 3's work
17
29
 
18
30
  ## MANDATORY SEQUENCE
19
31
 
32
+ **Pre-flight: the emitter and the run folder.** Both come first, so every later HALT can emit its envelope. Resolve `{emitEnvelopeHelper}` from `{emitEnvelopeProbeOrder}`; first existing path wins. It builds every `SKF_STACK_RESULT_JSON` line and the result files, and records each warning and auto-decision, so it stays bound for the whole run. If neither path exists, HALT (exit 3, `halt_reason: "helper-missing"`, phase `init:emitter`) and display only: "**Cannot proceed.** `skf-emit-result-envelope.py` is missing, so no result envelope can be built. Re-install SKF, then re-run." Then create the run folder:
33
+
34
+ ```bash
35
+ mkdir -p "{project-root}/_bmad-output/.skf-run" && mktemp -d "{project-root}/_bmad-output/.skf-run/skf-create-stack-skill-XXXXXXXX"
36
+ ```
37
+
38
+ Bind `{run_dir}` ← the path it prints: the run's state lives there until step 9 deletes it. If the command fails, HALT (exit 4, `halt_reason: "write-failure"`, phase `init:run-folder`): "**Cannot proceed.** The run folder could not be created: {the first stderr line}." With no folder to stage in, emit with the payload on stdin:
39
+
40
+ ```bash
41
+ uv run {emitEnvelopeHelper} emit-halt --workflow skf-create-stack-skill --target stderr <<'SKF_JSON'
42
+ {"phase": "init:run-folder", "halt_reason": "write-failure", "reason": "<the halt message, one line>"}
43
+ SKF_JSON
44
+ ```
45
+
46
+ **Halt envelope.** Every later HALT in this step names its exit code, `halt_reason` and phase. Stage `{run_dir}/halt.json` as `{"phase": "<phase>", "halt_reason": "<halt_reason>", "reason": "<the halt message, one line>", "skill_name": "{stack_name}"}`, leaving out `skill_name` before §0 binds `{stack_name}` and adding `"path"` when the halt names a file, then run:
47
+
48
+ ```bash
49
+ uv run {emitEnvelopeHelper} emit-halt --workflow skf-create-stack-skill --run-dir "{run_dir}" --target stderr < "{run_dir}/halt.json"
50
+ ```
51
+
52
+ Display the line it prints, then stop with the halt's exit code (`references/invocation-contract.md` lists every halt). If the emitter exits non-zero or prints no line, display the halt message alone.
53
+
54
+ **Warnings.** Each `workflow_warnings[]` entry this step appends is recorded at once: write its `[{step}/{severity}] {code}: {message}` line to `{run_dir}/warning.txt` with a file write, then run `uv run {emitEnvelopeHelper} record --run-dir "{run_dir}" --warning "$(cat "{run_dir}/warning.txt")"`.
55
+
56
+ **Resolver warning.** When SKILL.md On Activation bound `{customization_resolver_unavailable}` (the customization resolver could not run, so the `{project-root}/_bmad/custom/` overrides do not apply), record it now, as the run's first warning: write `[activation/warn] customization_resolver_unavailable: {customization_resolver_unavailable}` to `{run_dir}/warning.txt` with a file write, never an `echo` or a quoted `--warning` argument (a resolver error can hold quotes or `$( )`), then run the `record` command above.
57
+
20
58
  ### 0. Validate Project Config
21
59
 
22
- Before anything else, load `{project-root}/_bmad/skf/config.yaml`. If the file is missing OR fails YAML parse OR lacks the required top-level keys (`project_name`, `output_folder`, `skills_output_folder`, `forge_data_folder`, `sidecar_path`), HALT with:
60
+ Load `{project-root}/_bmad/skf/config.yaml`. If the file is missing OR fails YAML parse OR lacks the required top-level keys (`project_name`, `output_folder`, `skills_output_folder`, `forge_data_folder`, `sidecar_path`), HALT with:
23
61
 
24
62
  "**Cannot proceed.** SKF is not initialized for this project (config.yaml missing or malformed).
25
63
 
@@ -27,12 +65,16 @@ Before anything else, load `{project-root}/_bmad/skf/config.yaml`. If the file i
27
65
 
28
66
  **Halting workflow.**"
29
67
 
30
- Then emit the result envelope on stderr per the Result Contract in SKILL.md (`project_name` is unresolved here, so `skill_name` is `null`), and STOP — do not proceed:
68
+ That is a HALT (exit 2, `halt_reason: "config-missing"`, phase `init:config`), emitted per the halt envelope above with no `skill_name`: `project_name` is unresolved here.
31
69
 
32
- ```
33
- SKF_STACK_RESULT_JSON: {"status":"error","skill_package":null,"skill_name":null,"stack_libraries":[],"mode":null,"exit_code":2,"halt_reason":"config-missing"}
70
+ **Stack name.** Every later envelope and path names the stack, so bind `{stack_name}` now: the `stack_name` input, with `-stack` appended when it does not already end in it (`acme-web` gives `acme-web-stack`), else `{project_name}-stack`. When the input was given, check the bound name with the name rule step 7's pre-commit check applies to the stack's folder. Resolve `{frontmatterValidator}` from `{frontmatterValidatorProbeOrder}`; first existing path wins. If no candidate exists, HALT (exit 3, `halt_reason: "helper-missing"`, phase `init:stack-name`, no `skill_name`) with "**Cannot proceed.** `skf-validate-frontmatter.py` is missing, so SKF cannot check `stack_name`. Re-install SKF, then re-run." Otherwise run:
71
+
72
+ ```bash
73
+ uv run {frontmatterValidator} --check-name {stack_name}
34
74
  ```
35
75
 
76
+ On exit `1` (a name over 64 characters, two hyphens in a row, an upper-case letter or another character the rule refuses), HALT (exit 2, `halt_reason: "input-invalid"`, phase `init:stack-name`, no `skill_name`: the name was refused) with "**Cannot proceed.** `stack_name` `{value}` gives `{stack_name}`, which is not a skill name: {each `issues[]` message}. Fix the input and re-run."
77
+
36
78
  ### 1. Load Forge Tier Configuration
37
79
 
38
80
  Load `{forgeTierFile}` from the Ferris sidecar.
@@ -45,11 +87,7 @@ Load `{forgeTierFile}` from the Ferris sidecar.
45
87
 
46
88
  **Halting workflow.**"
47
89
 
48
- Then emit the result envelope on stderr per the Result Contract in SKILL.md (config loaded, so `skill_name` is known; `mode` is not yet resolved), and STOP — do not proceed:
49
-
50
- ```
51
- SKF_STACK_RESULT_JSON: {"status":"error","skill_package":null,"skill_name":"{project_name}-stack","stack_libraries":[],"mode":null,"exit_code":3,"halt_reason":"forge-tier-missing"}
52
- ```
90
+ That is a HALT (exit 3, `halt_reason: "forge-tier-missing"`, phase `init:forge-tier`, `path` `{forgeTierFile}`), emitted per the halt envelope above.
53
91
 
54
92
  **If forge-tier.yaml exists:**
55
93
 
@@ -68,7 +106,7 @@ Extract:
68
106
  **Tier-dependent tools:**
69
107
  - **Quick:** gh_bridge (source reading) — graceful degradation to local file reading if unavailable
70
108
  - **Forge:** ast_bridge (ast-grep structural analysis) — required for Forge tier
71
- - **Forge+:** ast_bridge + ccc_bridge (ccc semantic co-import augmentation) — ccc available for step 5
109
+ - **Forge+:** ast_bridge + ccc_bridge (CCC semantic search, which step 5 uses to pick the files that best show each integration)
72
110
  - **Deep:** qmd_bridge (QMD temporal enrichment) — required for Deep tier
73
111
 
74
112
  See `knowledge/tool-resolution.md` for how each bridge name resolves to concrete tools per IDE environment.
@@ -77,39 +115,59 @@ Report tool availability. If a tier-required tool is missing, downgrade tier and
77
115
 
78
116
  "**Tier adjusted:** {original_tier} → {adjusted_tier} — {missing_tool} unavailable."
79
117
 
80
- ### 3. Accept Optional Inputs
118
+ ### 3. Bind Inputs and Choose the Mode
119
+
120
+ **Inputs.** Bind each input the invocation gives (`references/invocation-contract.md` lists them; `stack_name` is bound in §0), and check them all before the first question below:
121
+
122
+ - `skills` → `explicit_deps`: a value that names an existing file is a list, one name per line; any other value is comma-separated names. In code mode they are the libraries to rank, and step 2 skips the manifest scan; in compose mode they are the constituent skills, each a skill folder name or a package path, which step 2's helper reduces to its skill folder.
123
+ - `scope_overrides` → `scope_overrides`: `name: include` or `name: exclude` entries, which step 3 applies.
124
+ - `architecture_doc_path` → `architecture_doc_path`: the document compose mode maps integrations from.
125
+ - `mode` → `code` or `compose`.
126
+ - `project_path` → `{scan_root}` (below).
127
+
128
+ A `mode` other than `code` or `compose`, a `scope_overrides` value other than `include` or `exclude`, a `skills` list file that cannot be read, an `architecture_doc_path` that is not a readable file, or a `project_path` that is not a folder HALTs (exit 2, `halt_reason: "input-invalid"`, phase `init:inputs`) with "**Cannot proceed.** `{input}`: {why}. Fix the input and re-run."
81
129
 
82
- Check if the user provided:
130
+ **Scan root.** `{scan_root}` is the folder code mode reads: step 2 scans its manifests, step 3 counts the imports in it, and step 5 pairs libraries by those counts. It is `project_path` when given (a relative path resolves from `project_root`), else `project_root`. Compose mode reads no source code, so it never uses `{scan_root}`: a `project_path` given to a compose-mode run is not read, and the run appends `{step: "step-01", severity: "warn", code: "project-path-ignored", message: "compose mode reads no source code: project_path not read"}` to `workflow_warnings[]`.
83
131
 
84
- **Explicit dependency list:**
85
- - If provided, store as `explicit_deps` and skip auto-detection in step 02
86
- - Format: comma-separated library names or a file path
132
+ **Mode.** The first rule that applies sets `compose_mode`:
87
133
 
88
- **Scope overrides:**
89
- - If provided, store as `scope_overrides` for use in step 03
90
- - Format: `library_name: include|exclude`
134
+ 1. `mode` is `compose`: `compose_mode: true`.
135
+ 2. `mode` is `code`: `compose_mode: false`. An `architecture_doc_path` given with it is not read: append `{step: "step-01", severity: "warn", code: "architecture-doc-ignored", message: "mode code reads no architecture document"}` to `workflow_warnings[]`.
136
+ 3. `architecture_doc_path` was given: `compose_mode: true`.
137
+ 4. Otherwise two helpers decide. Resolve `{scanManifestsHelper}` from `{scanManifestsProbeOrder}` and `{enumerateStackSkillsHelper}` from `{enumerateStackSkillsProbeOrder}`; first existing path wins. When one has no candidate, HALT (exit 3, `halt_reason: "helper-missing"`, phase `init:mode`) with "**Cannot proceed.** `{script}` is missing, so SKF cannot choose the mode. Re-install SKF, then re-run." Scan `{scan_root}` and keep the JSON as `{manifest_scan}`, which step 2 reuses:
91
138
 
92
- **Compose mode detection:**
139
+ ```bash
140
+ uv run {scanManifestsHelper} scan {scan_root} --include-dev
141
+ ```
93
142
 
94
- Set `compose_mode: false` as the default.
143
+ When its `manifests` is empty, list the skills compose mode could build from, passing `--explicit` with the `explicit_deps` entries as given, comma-separated, when this section bound them, and keep the JSON as `{skill_candidates}`, which step 2 reuses (an exit `1`, no skills folder, means none):
95
144
 
96
- Skills use version-nested directories — see `knowledge/version-paths.md` for the full path templates and resolution rules.
145
+ ```bash
146
+ uv run {enumerateStackSkillsHelper} candidates {skills_output_folder} [--explicit "<names>"]
147
+ ```
97
148
 
98
- - If user provides an architecture document path for composition or explicitly requests compose mode → set `compose_mode: true` and store `architecture_doc_path`
99
- - If no manifest files exist in project root AND at least one skill is discoverable in `{skills_output_folder}` → suggest compose mode to the user and ask for optional architecture document path
100
- - **Skill discovery (version-aware):** First, read `{skills_output_folder}/.export-manifest.json` — each entry in `exports` names a skill with an `active_version`, which resolves to `{skills_output_folder}/{skill-name}/{active_version}/{skill-name}/` containing `SKILL.md` and `metadata.json`. If the export manifest does not exist or is empty, fall back to scanning for `active` symlinks: check `{skills_output_folder}/*/active/*/SKILL.md` — each match indicates a skill whose package lives at `{skills_output_folder}/{skill-name}/active/{skill-name}/` (the `{active_skill}` template).
101
- - **Headless default (B8):** If `{headless_mode}` is true, do NOT prompt — auto-accept the suggestion: set `compose_mode: true` and `architecture_doc_path: null` (unless an architecture doc path was supplied via the optional inputs above). This is the constructive default: with no manifests present, code-mode would only halt at step 2 (`no-manifests`), so compose is the sole path that produces output. Log the auto-decision by appending to `workflow_warnings[]`: `{step: "step-01", severity: "info", code: "headless-compose-autodetect", message: "no manifests + {N} discoverable skills — auto-selected compose mode", context: {discoverable_skills: {N}}}`.
102
- - If user accepts → set `compose_mode: true` and store `architecture_doc_path` (may be `null` if user chose not to provide one)
103
- - If user declines → `compose_mode` remains `false`, continue with code-mode
149
+ When its `kept[]` is not empty, suggest compose mode, naming its `{N}` skills, and ask for an optional architecture document path (ask again for a path that is not a readable file). If the user accepts, set `compose_mode: true` and store `architecture_doc_path` (`null` when the user gives none); if the user declines, code mode stays. In every other case the run uses code mode: step 2 ranks `explicit_deps` when given.
150
+
151
+ **GATE [default: accept]**, headless default (B8): do NOT prompt: accept the suggestion (`compose_mode: true`, `architecture_doc_path: null`). With no manifests, code mode would only halt at step 2 (`no-manifests`) or rank `explicit_deps` in a tree that declares none of them, while `kept[]` holds SKF skills (those `explicit_deps` names, when given): compose is the path that produces the stack. Record the auto-decision: stage `{"gate": "init.compose-suggestion", "default_action": "accept", "taken_action": "accept", "reason": "headless: no manifests and {N} SKF skills, so compose mode", "evidence": {"discoverable_skills": {N}}}` as `{run_dir}/decision.json` and run:
152
+
153
+ ```bash
154
+ uv run {emitEnvelopeHelper} record --workflow skf-create-stack-skill --run-dir "{run_dir}" --decision < "{run_dir}/decision.json"
155
+ ```
156
+
157
+ **Scan scope (code mode).** Run the scan call above (resolving `{scanManifestsHelper}` as rule 4 does) when rule 2 set the mode, so `{manifest_scan}` holds the scan of `{scan_root}`. When its `folders[]` lists more than one folder and no `project_path` was given, ask once which folder the stack covers:
158
+
159
+ "**This project holds several packages.** Type **A** to build the stack for the whole project (the default), or the folder of one package: {each `folders[]` entry's `path`, with its `names`}."
160
+
161
+ A folder answer resolves from `project_root`. When it is no folder, ask again; otherwise set `{scan_root}` to it and run the scan call again, replacing `{manifest_scan}`. **GATE [default: A]**: headless, do not ask; keep the project root, record the auto-decision as B8 does, with `{"gate": "init.scan-root", "default_action": "A", "taken_action": "A", "reason": "headless: manifests in {N} folders, so the whole project; pass project_path to scan one package", "evidence": {"folders": {N}}}`, `{N}` being the `folders[]` count: its `reason` tells the user to pass `project_path`.
162
+
163
+ Skills use version-nested directories: see `knowledge/version-paths.md` for the path templates.
104
164
 
105
165
  If compose_mode:
106
166
  - Display: "**Compose mode detected.** Synthesizing stack skill from existing skills + architecture document."
107
167
 
108
- If no optional inputs provided, auto-detection will be used.
109
-
110
168
  ### 4. Display Initialization Summary
111
169
 
112
- Report that the Stack Skill Forge is initialized, naming: the project (`{project_name}`); the forge tier (`{forge_tier}`) with its positive-capability framing (Quick = source reading and import counting; Forge = AST-backed structural analysis; Forge+ = AST structural + CCC semantic co-import augmentation; Deep = full intelligence — structural + contextual + temporal); the available tools (`{tool_list}`); and the resolved input mode (auto-detect, explicit dependency list, or compose mode).
170
+ Report that the Stack Skill Forge is initialized, naming: the project (`{project_name}`); the forge tier (`{forge_tier}`) with its positive-capability framing (Quick = source reading and import counting; Forge = AST-backed structural analysis; Forge+ = AST structural + CCC semantic search for the files that show each integration; Deep = full intelligence: structural + contextual + temporal); the available tools (`{tool_list}`); the stack name (`{stack_name}`); and the resolved input mode (auto-detect, explicit dependency list, or compose mode), with the folder code mode scans (`{scan_root}`).
113
171
 
114
172
  ### 5. Auto-Proceed to Next Step
115
173
 
@@ -2,22 +2,6 @@
2
2
 
3
3
  # Integration Pattern Detection Rules
4
4
 
5
- ## Co-Import Detection
6
-
7
- A co-import is detected when two or more confirmed libraries are imported in the same source file.
8
-
9
- ### Detection Method
10
-
11
- 1. For each file in the codebase, extract all import statements
12
- 2. Map imports to confirmed library list
13
- 3. If a file imports 2+ confirmed libraries → co-import detected
14
- 4. Record: file path, library pair, line numbers
15
-
16
- ### Minimum Threshold
17
-
18
- - A library pair must co-appear in **2+ files** to qualify as an integration pattern
19
- - Single file co-imports may be incidental
20
-
21
5
  ## Integration Pattern Types
22
6
 
23
7
  ### Type 1: Middleware Chain
@@ -59,5 +43,5 @@ Library A + Library B
59
43
  Files: [count] files with co-imports
60
44
  Key files: [top 3 files by integration density]
61
45
  Pattern: [brief description of how they integrate]
62
- Confidence: [weaker of the two libraries' tiers from per_library_extractions[], with detection-method qualifier in parens — e.g., `T1-low (grep-co-import)`, `T1 (ccc-augmented)`, `T1-low (architecture-co-mention) [composed]`. Integration detection is grep + co-import, never AST — do not label integrations "AST-verified".]
46
+ Confidence: [the pair tier step 5 §3 takes from skf-render-stack-metadata.py, with the detection-method qualifier in parens, e.g. `T1-low (grep-co-import)`, `T1 (grep-co-import)`, `T1-low (architecture-co-mention) [composed]`. Integration detection is co-import evidence from the import counts, never AST: do not label integrations "AST-verified".]
63
47
  ```
@@ -0,0 +1,34 @@
1
+ # Invocation Contract
2
+
3
+ The headless contract of Stack Skill: its inputs, gates and outputs, the exit code and `halt_reason` of every HARD HALT, and the result envelope. A halting step names its exit code, `halt_reason` and phase and shows the emit command, so it needs nothing else from this file.
4
+
5
+ | Aspect | Detail |
6
+ |--------|--------|
7
+ | **Inputs** | All optional; step 1 binds and checks each one, and halts with `input-invalid` on a value it cannot use. `project_path`: the folder code mode scans (default: the project root; an interactive run asks once when the manifests sit in several folders). `skills`: the libraries to rank, or the constituent skills in compose mode. `stack_name`: the stack's skill name (default `{project_name}-stack`). `scope_overrides`: step 3 scope overrides. `architecture_doc_path`: the document compose mode reads. `mode`: `code` or `compose` (default: step 1 detects it) |
8
+ | **Gates** | step 1: compose suggestion [accept] and scan scope [A] (each asked only in an interactive run; headless takes the default and records it); step 2: no manifest found (headless: HALT `no-manifests`, exit 2); step 3: scope gate [C]; step 6: review gate [C] |
9
+ | **Outputs** | SKILL.md (stack), context-snippet.md, metadata.json; `provenance-map.json` and `evidence-report.md` in `{forge_version}`; the result contract, `create-stack-skill-result-{YYYYMMDD-HHmmss}.json` and its `create-stack-skill-result-latest.json` copy in `{forge_version}`, with the `-latest` copy also at the stack group root `{forge_data_folder}/{stack_name}/`; a run folder under `{project-root}/_bmad-output/.skf-run/`, deleted when the run finishes or the user cancels and kept after any other HALT |
10
+ | **Headless** | All gates auto-resolve with their default action when `{headless_mode}` is true, and each records its decision in the run sink, so the envelope's `headless_decisions` lists every one |
11
+ | **Exit codes** | See "Exit Codes" below |
12
+
13
+ ## Exit Codes
14
+
15
+ Every HARD HALT in this workflow exits with a stable code so headless automators can branch on the failure class without grepping message text:
16
+
17
+ | Code | Meaning | Raised by (halt_reason) |
18
+ | ---- | -------------------- | ------------------------------------------------------------------------------------------ |
19
+ | 0 | success | step 10 (terminal handoff to shared health-check) |
20
+ | 2 | input / precondition invalid | step 1 §0 `config.yaml` missing/malformed (`config-missing`); step 1 §0 or §3 an input it cannot use (`input-invalid`); step 2 §2 headless with no manifests (`no-manifests`, S2); step 4 §3 all extractions failed (`all-extractions-failed`, B7); step 5 §2 a feasibility report of another `schemaVersion` (`schema-version-mismatch`) or with a verdict token outside the schema's set (`unknown-verdict-token`) |
21
+ | 3 | resolution-failure | step 1 §1 `forge-tier.yaml` missing (`forge-tier-missing`); a shared helper that resolves to no path (`helper-missing`): `skf-emit-result-envelope.py` (step 1 pre-flight), `skf-validate-frontmatter.py` (step 1 §0), `skf-scan-manifests.py` or `skf-enumerate-stack-skills.py` (step 1 §3, step 2 §0 and §2, step 4 §0), `skf-count-imports.py` (step 3 §1), `skf-render-stack-metadata.py` (step 4 §3a, step 5 §3, step 6 §1, step 7 §6), `skf-pair-intersect.py` (step 5 §1), `skf-comention-pairs.py` (step 5 §2), `skf-atomic-write.py` (step 7 §1); step 2 §0 compose-mode stale manifest (a manifest key whose skill folder is gone) or zero qualifying skills (S1/B4), step 4 §0 compose cycle among confirmed skills or a confirmed skill no longer an SKF package (`resolution-failure`) |
22
+ | 4 | write-failure | step 1 pre-flight: the run folder cannot be created; step 7: a stage-dir, write or commit-dir failure (the §1 rollback contract), or a group-dir collision when an existing non-stack skill occupies the target path (`write-failure`) |
23
+ | 5 | state-conflict | step 7 §1 ownership check (S3, both phases): the stack's folder in skills_output_folder, or the version folder this run writes, is not SKF output or SKF cannot check it (`not-skf-output`); an SKF stack still in the flat layout (`flat-layout`) |
24
+ | 6 | user-cancelled | step 2 §2 option 3 (no manifests, interactive); `[X]` Cancel and exit at the step 3 scope gate or the step 6 review gate (`user-cancelled`) |
25
+
26
+ ## Result Contract (Headless)
27
+
28
+ The shared emitter, `skf-emit-result-envelope.py`, builds every `SKF_STACK_RESULT_JSON: {...}` line from the payload a step stages in `{run_dir}`, folds in the decisions and warnings the run recorded there, derives `exit_code` from `halt_reason`, stamps `run_id` and `result_path`, and checks the line against `shared/scripts/schemas/skf-stack-result-envelope.v1.json` (installed under `{project-root}/_bmad/skf/`), whose descriptions say what each field holds. Never type the line yourself. Every HARD HALT prints one on **stderr**, in every mode, with `status: "error"`, except the `init:emitter` halt, which has no emitter to print one; step 9 prints the success line on **stdout** and displays it when `{headless_mode}` is true, before chaining to step 10:
29
+
30
+ ```
31
+ SKF_STACK_RESULT_JSON: {"status":"success|error","skill_package":"...|null","skill_name":"...","stack_libraries":["..."],"mode":"code|compose","quality_score":null,"exit_code":0,"halt_reason":null,"run_id":"...","result_path":"...|null","headless_decisions":[],"warnings":[]}
32
+ ```
33
+
34
+ A halt adds `error`: its `phase`, its message as `reason`, and `path` when it names a file or folder. When the customization resolver could not run, `warnings` holds `[activation/warn] customization_resolver_unavailable: <reason>`, which step 1 records before any other warning: the run used the bundled `customize.toml` alone, without the `{project-root}/_bmad/custom/` overrides.
@@ -4,26 +4,38 @@
4
4
 
5
5
  ## Supported Ecosystems
6
6
 
7
- | Ecosystem | Manifest File(s) | Dependency Key | Import Pattern |
8
- |-----------------------|-----------------------------------------------------|------------------------------------------|-------------------------------------------|
9
- | JavaScript/TypeScript | package.json | dependencies, devDependencies | `import ... from '...'`, `require('...')` |
10
- | Python | requirements.txt, setup.py, pyproject.toml, Pipfile | install_requires, [project.dependencies] | `import ...`, `from ... import` |
11
- | Rust | Cargo.toml | [dependencies] | `use ...`, `extern crate` |
12
- | Go | go.mod | require | `import "..."` |
13
- | Java | pom.xml, build.gradle | dependencies | `import ...` |
14
- | Ruby | Gemfile | gem | `require '...'`, `require_relative` |
15
- | PHP | composer.json | require, require-dev | `use ...`, `require_once` |
16
- | .NET | *.csproj | PackageReference | `using ...` |
17
-
18
- <!-- Manifest scanning, name normalization, dedup, exclusion-dir filtering, and
19
- dev/build-tool filtering are performed by `skf-scan-manifests.py` (invoked in
20
- detect-manifests.md §2), which implements exactly the ecosystem table above.
21
- This file is loaded only for that reference table and the import-counting
22
- exclusions below — see the script's `--help` for the operative scan contract. -->
7
+ `skf-scan-manifests.py` (invoked in detect-manifests.md §2) finds exactly the manifest files below and no others; the same list is its `searched_filenames[]`. The Ecosystem column is the value it writes in each manifest's `ecosystem` field. The table mirrors the script's `MANIFEST_ECOSYSTEMS`, and `test/test-skf-scan-manifests.py` fails when the two drift.
8
+
9
+ | Ecosystem | Language | Manifest files | Runtime dependencies | Dev dependencies (`scope: dev`) | Import syntax counted |
10
+ |------------|-----------------------|--------------------------------------------------------------------------|------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------|------------------------------------------------------------|
11
+ | `npm` | JavaScript/TypeScript | `package.json` | `dependencies` | `devDependencies` | `import ... from '...'`, `import('...')`, `require('...')` |
12
+ | `python` | Python | `pyproject.toml`, `requirements.txt`, `setup.py`, `setup.cfg`, `Pipfile` | `[project] dependencies`, `[tool.poetry.dependencies]`, `install_requires`, `[packages]` | `[dependency-groups]`, dev extras, Poetry groups, `tests_require`, `[dev-packages]` | `import ...`, `from ... import ...` |
13
+ | `rust` | Rust | `Cargo.toml` | `[dependencies]` | `[dev-dependencies]` | `use ...`, `extern crate ...`, `crate_name::path` |
14
+ | `go` | Go | `go.mod` | `require` | none | `import "..."` |
15
+ | `maven` | Java/Kotlin | `pom.xml` | `<dependency>` outside the `test`, `provided` and `system` scopes | `<scope>test</scope>` | `import ...` |
16
+ | `gradle` | Java/Kotlin | `build.gradle`, `build.gradle.kts` | `implementation`, `api`, `compile`, `runtimeOnly` | `test*` and `androidTest*` configurations | `import ...` |
17
+ | `ruby` | Ruby | `Gemfile` | `gem` | `gem` inside a `group :development` or `:test` block | `require '...'` |
18
+ | `composer` | PHP | `composer.json` | `require` (not `php` or `ext-*`) | `require-dev` | `use ...` |
19
+ | `swift` | Swift | `Package.swift` | `.package(url: ...)` | none | `import ...` |
20
+
21
+ The scanner reports runtime dependencies by default; `--include-dev` adds the dev ones, each tagged `scope: dev`. For each manifest it also reports the package's own `name`, whether it is `private` (not published) and its `internal_deps`, the other scanned packages of the same ecosystem it depends on at runtime; `umbrella_candidates` lists the published packages that depend on at least 2, and at least half, of the other published members of their ecosystem (a facade that may re-export them). The script's docstring states the exact rules.
22
+
23
+ ## Scan Exclusion Patterns
24
+
25
+ The scanner never descends into `node_modules/`, `.venv/`, `venv/`, `.env/`, `vendor/`, `Pods/`, `dist/`, `build/`, `out/`, `target/`, `__pycache__/`, `.next/`, `.nuxt/`, `.output/` or `.git/`, nor into any other directory whose name starts with a dot.
23
26
 
24
27
  ## Import Counting
25
28
 
26
- For each dependency, count distinct files that import it:
27
- - Use grep patterns from Import Pattern column
28
- - Count unique file paths, not total import statements
29
- - Exclude test files (`*/test/*`, `*_test.*`, `*.spec.*`, `*.test.*`), config files (`*.config.*`, `.eslintrc`, etc.), and build artifacts (`dist/`, `build/`, `node_modules/`, `target/`, `__pycache__/`) from count
29
+ Import counts follow these rules, which `skf-count-imports.py` implements:
30
+
31
+ - Count the distinct files that import each dependency, not the import statements: a file counts once, with the first line that imports the dependency.
32
+ - Match on module boundaries: `react` counts `import ... from 'react'` and `'react/jsx-runtime'`, never `react-dom` or `react-router`; `yaml` counts `yaml` and `yaml.loader`, never `yamlordereddict`.
33
+ - Map distribution names to import names: `PyYAML` is imported as `yaml`, `Pillow` as `PIL`, `beautifulsoup4` as `bs4`, `scikit-learn` as `sklearn`. A name outside the script's tables is guessed by a naming rule: a Python distribution as its name with `-` read as `_`, `google-cloud-storage` as `google.cloud.storage`, `@types/react` as `react`, `symfony/framework-bundle` as `Symfony\Bundle\FrameworkBundle`. A guess that matches no file goes to `unresolved[]` for you to judge instead of counting 0.
34
+ - A dependency imported by 2 or more files is `above_threshold`.
35
+
36
+ Excluded paths (a pattern ending in `/` names a directory at any depth; a pattern with no `/` matches a file name at any depth):
37
+
38
+ - Hidden files and directories: `.*/`, `.*`
39
+ - Tests: `test/`, `tests/`, `__tests__/`, `spec/`, `*.test.*`, `*.spec.*`, `*_test.*`, `test_*.py`, `*_spec.rb`, `conftest.py`
40
+ - Config and build scripts: `*.config.*`, `setup.py`, `noxfile.py`, `*.gradle.kts`, `Package.swift`
41
+ - Build output and vendored code: `dist/`, `build/`, `out/`, `target/`, `node_modules/`, `vendor/`, `venv/`, `Pods/`, `__pycache__/`