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
@@ -3,6 +3,16 @@ nextStepFile: 'detect-integrations.md'
3
3
  enumerateStackSkillsProbeOrder:
4
4
  - '{project-root}/_bmad/skf/shared/scripts/skf-enumerate-stack-skills.py'
5
5
  - '{project-root}/src/shared/scripts/skf-enumerate-stack-skills.py'
6
+ renderStackMetadataProbeOrder:
7
+ - '{project-root}/_bmad/skf/shared/scripts/skf-render-stack-metadata.py'
8
+ - '{project-root}/src/shared/scripts/skf-render-stack-metadata.py'
9
+ emitEnvelopeProbeOrder:
10
+ - '{project-root}/_bmad/skf/shared/scripts/skf-emit-result-envelope.py'
11
+ - '{project-root}/src/shared/scripts/skf-emit-result-envelope.py'
12
+ bundleFile: '{run_dir}/extraction-bundle.json'
13
+ exportRecordsFile: '{run_dir}/export-records.json'
14
+ importCountsFile: '{run_dir}/import-counts.json'
15
+ stackInventoryFile: '{run_dir}/stack-inventory.json'
6
16
  ---
7
17
 
8
18
  <!-- Config: communicate in {communication_language}. -->
@@ -17,31 +27,62 @@ For each confirmed dependency, extract key exports, usage patterns, and API surf
17
27
 
18
28
  - Extract per-library using subprocess Pattern 4 (parallel) when available; if unavailable, extract sequentially
19
29
  - Each subprocess returns structured extraction, not raw file contents
30
+ - Label each export by the tool that read it, never by the forge tier
20
31
  - Do not analyze cross-library integrations (Step 05)
21
32
 
22
33
  ## MANDATORY SEQUENCE
23
34
 
35
+ **Halt envelope.** Every 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}", "mode": "<code|compose>", "stack_libraries": ["<confirmed library>", ...]}`, then run:
36
+
37
+ ```bash
38
+ uv run {emitEnvelopeHelper} emit-halt --workflow skf-create-stack-skill --run-dir "{run_dir}" --target stderr < "{run_dir}/halt.json"
39
+ ```
40
+
41
+ Display the line it prints, then stop with the halt's exit code (`references/invocation-contract.md` lists every halt). If `{emitEnvelopeHelper}` is not bound, resolve it from `{emitEnvelopeProbeOrder}`; if no path exists, or the emitter exits non-zero or prints no line, display the halt message alone.
42
+
43
+ **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")"`.
44
+
45
+ **Extraction bundle.** What this step extracts goes to `{bundleFile}`, so no later step works from memory: step 5 reads each library's tier there and adds the pairs it keeps, step 6 compiles from it, and step 7 writes the reference files, `metadata.json` and the provenance map from it. It is one JSON object, written with the run's other files in `{run_dir}`:
46
+
47
+ ```json
48
+ {
49
+ "mode": "code|compose",
50
+ "scope": ["<confirmed library>"],
51
+ "per_library_extractions": [
52
+ {"library": "<name>", "status": "success|partial", "version": "<version>",
53
+ "confidence": "T1|T1-low|T2|T3", "files_analyzed": 0,
54
+ "usage_patterns": ["<pattern with file:line>"], "warnings": [], "temporal": {}}
55
+ ],
56
+ "failed": [{"library": "<name>", "reason": "<why>"}],
57
+ "integrations": [],
58
+ "hubs": [],
59
+ "cross_cutting": []
60
+ }
61
+ ```
62
+
63
+ `scope` is step 3's `confirmed_dependencies`; step 5 fills `integrations`, `hubs` and `cross_cutting`. A compose-mode entry also holds `skill_dir`, `skill_package_path`, `exports`, `exports_source` and `source_authority` (§0). A code-mode entry also holds `file_count`, the library's step 3 import count, and its export records sit beside the bundle in `{exportRecordsFile}` (§3a).
64
+
24
65
  ### 0. Check Compose Mode
25
66
 
26
67
  **If `compose_mode` is true:**
27
68
 
28
69
  "**Extraction data already available from individual skills. Skipping extraction phase.**"
29
70
 
30
- For each confirmed skill, load SKILL.md from the version-aware path resolved in step 2.
71
+ For each confirmed skill, load SKILL.md from its `skill_package_path` (step 2, refreshed below): its usage patterns come from there.
31
72
 
32
- **Re-resolve at step 4 entry (S17):** Between step 2 manifest detection and step 4 extraction, a concurrent write could have advanced a skill's `active_version`. On entering this step, re-resolve `skill_package_path` for each confirmed skill via the export-manifest (or symlink fallback) and capture the freshly-read `version` and `metadata_hash` into workflow state. If the `metadata_hash` diverges from the value stored in step 2, log a warning `"constituent '{skill_name}' changed between step 2 and step 4 — using fresh values"` and replace the workflow-state entry (so step 7 provenance records the hash active at extraction time, with the drift logged for audit).
73
+ **Re-resolve at step 4 entry (S17):** a concurrent write could have advanced a skill's version between step 2 and step 4. Re-resolve each confirmed skill from this step's helper result below: the `skills[]` entry whose `name` is its `skill_dir` gives the fresh `skill_package_path` (`{skills_output_folder}/{path}`) and `metadata_hash`. **The provenance anchor (S13) is the hash of the package this step reads**: step 2's value, unless the package changed since. When the `metadata_hash` diverges from the value step 2 stored, append a `workflow_warnings[]` entry (`step: "step-04"`, `severity: "warn"`, `code: "constituent-changed"`, `message`: "constituent '{skill_name}' changed between step 2 and step 4: using fresh values") and replace the workflow-state entry. If a confirmed skill has no `skills[]` entry now, HALT (exit 3, `halt_reason: "resolution-failure"`, phase `parallel-extract:constituent-gone`) with "constituent `{skill_dir}` is no longer an SKF skill package: re-run [SS]."
33
74
 
34
- Use `skill_package_path` (stored in step 2 and optionally refreshed above) directly — this already points to the resolved `{skill_package}` or `{active_skill}` directory containing the skill's artifacts. If `skill_package_path` is not available, resolve via the `{active_skill}` template: `{skills_output_folder}/{skill_dir}/active/{skill_dir}/SKILL.md` (see `knowledge/version-paths.md`).
75
+ Use `skill_package_path` directly — it points to the package the helper resolved.
35
76
 
36
- **Exports resolution order (H1) — script-driven:** Do NOT walk per-skill `metadata.json` → `references/` → SKILL.md by hand. Invoke the helper once at step entry to compute the full inventory for every confirmed skill in one deterministic call:
77
+ **Exports resolution order (H1), script-driven:** Do NOT walk per-skill `metadata.json` → `references/` → SKILL.md by hand. Invoke the helper once at step entry to compute the full inventory for every confirmed skill in one deterministic call:
37
78
 
38
- **Resolve `{enumerateStackSkillsHelper}`** from `{enumerateStackSkillsProbeOrder}`; first existing path wins. HALT if no candidate exists.
79
+ **Resolve `{enumerateStackSkillsHelper}`** from `{enumerateStackSkillsProbeOrder}`; first existing path wins. If no candidate exists, HALT (exit 3, `halt_reason: "helper-missing"`, phase `parallel-extract:enumerate`) with "**Cannot proceed.** `skf-enumerate-stack-skills.py` is missing, so no constituent's exports can be read. Re-install SKF, then re-run."
39
80
 
40
81
  ```bash
41
- uv run {enumerateStackSkillsHelper} enumerate {skills_output_folder}
82
+ uv run {enumerateStackSkillsHelper} enumerate {skills_output_folder} > "{stackInventoryFile}"
42
83
  ```
43
84
 
44
- The script emits JSON of the form:
85
+ Its JSON, in `{stackInventoryFile}`, has the form:
45
86
 
46
87
  ```json
47
88
  {
@@ -52,34 +93,40 @@ The script emits JSON of the form:
52
93
  "exports": ["..."],
53
94
  "exports_source": "metadata|references|skill-md|unknown",
54
95
  "confidence": "T1|T2|T1-low",
55
- "metadata_hash": "sha256:..." | null
96
+ "evidence_tier": "T1|T1-low|T2|T3",
97
+ "metadata_hash": "sha256:..."
56
98
  }
57
99
  ],
58
100
  "cycles": ["<skill-name>"],
59
- "warnings": ["<text>"]
101
+ "warnings": ["<text>"],
102
+ "not_skf_output": ["<skill-name>"]
60
103
  }
61
104
  ```
62
105
 
63
- Cache this result as `stack_skill_inventory` in workflow state — the per-skill subagent fan-out at §1+ MUST read from this cache rather than re-reading each skill's `SKILL.md` / `metadata.json` / `references/` to determine exports. Append every entry in `warnings[]` to workflow state for the evidence report (the script already labels them per-skill, e.g. `"<skill-name>: no exports found via any resolution path"`). If `cycles[]` is non-empty, a composes-cycle makes the stack unbuildable — emit the result envelope on stderr per the Result Contract in SKILL.md and exit `3`:
106
+ §0 reads this JSON from `{stackInventoryFile}`: each constituent's exports come from it, never from memory or from re-reading its `SKILL.md`, `metadata.json` or `references/`. Append to `workflow_warnings[]` the `warnings[]` entries that name a confirmed skill (each starts with `<skill_dir>: `, e.g. `"<skill-name>: no exports found via any resolution path"`). If `cycles[]` names a confirmed skill, a composes-cycle makes the stack unbuildable: HALT (exit 3, `halt_reason: "resolution-failure"`, phase `parallel-extract:cycle`) with "composes cycle among the confirmed skills: {the `cycles[]` names}."
64
107
 
65
- ```
66
- SKF_STACK_RESULT_JSON: {"status":"error","skill_package":null,"skill_name":"{project_name}-stack","stack_libraries":[],"mode":"compose","exit_code":3,"halt_reason":"resolution-failure"}
67
- ```
68
-
69
- Build a `per_library_extractions[]` entry for each skill by reading from the cached inventory:
108
+ Build a `per_library_extractions[]` entry for each confirmed skill, from the `skills[]` entry whose `name` is its `skill_dir`:
70
109
  - `library`: `inventory.skills[i].name`
71
110
  - `exports`: `inventory.skills[i].exports`
72
111
  - `exports_source`: `inventory.skills[i].exports_source` (one of `metadata|references|skill-md|unknown` — capture for step 7 provenance)
73
- - `confidence`: `inventory.skills[i].confidence` (one of `T1|T2|T1-low`; `unknown` source ⇒ `T1-low`). Do not silently drop T3 evidence; carry whatever tier the source skill declared if §1+ subagent analysis upgrades the value.
74
- - `metadata_hash`: `inventory.skills[i].metadata_hash` — record for step 7 provenance (null when exports came from references/ or SKILL.md prose).
75
- - `usage_patterns`: populated by the §1+ per-skill subagent fan-out, NOT by this script. The script provides the inventory + exports; the subagent does the per-skill usage analysis. They're complementary.
112
+ - `confidence`: `inventory.skills[i].evidence_tier` (one of `T1|T1-low|T2|T3`), the library's tier, which steps 5 and 7 read. Never `inventory.skills[i].confidence`: it only says where the export list came from.
113
+ - No `metadata_hash`: step 7's provenance helper copies the anchor above from `{stackInventoryFile}` into `constituents[]`.
114
+ - `skill_dir`, `skill_package_path`, `version` and `source_authority`: from step 2's entry, the path refreshed above.
115
+ - `usage_patterns`: read from the constituent's `SKILL.md` loaded above, each with the file and line it cites there.
76
116
 
77
- Report the loaded extractions — for each skill: export count, confidence tier, and load status. Then auto-proceed to the next step.
117
+ Write `{bundleFile}`: `mode`, `scope` and these entries. Then report the loaded extractions: for each skill, export count, confidence tier, and load status. Then auto-proceed to the next step.
78
118
 
79
119
  **If not compose_mode:** Continue with section 1 (existing flow).
80
120
 
81
121
  ### 1. Prepare Extraction Plan
82
122
 
123
+ **Export labels, at every tier:**
124
+
125
+ - An export an ast-grep rule matched: `extraction_method: "ast_bridge"`, `confidence: "T1"`, `signature_source: "T1"`.
126
+ - An export read by eye, for any reason (Quick tier, ast-grep unavailable, a file ast-grep could not parse, a rule that matched nothing, or a file read instead of running a rule): `extraction_method: "source_reading"`, `confidence: "T1-low"`, `signature_source: "T1-low"`.
127
+
128
+ Deep-tier temporal findings are T2 annotations, never export labels.
129
+
83
130
  **AST Tool Availability Check (Forge/Deep only):**
84
131
 
85
132
  This workflow operates on local project files and installed library packages. Remote source resolution does not apply — libraries are analyzed as they exist within the project's dependency tree.
@@ -88,11 +135,11 @@ This workflow operates on local project files and installed library packages. Re
88
135
 
89
136
  ⚠️ **Warn the user explicitly:** "AST tools are unavailable — extraction will use source reading (T1-low). Run [SF] Setup Forge to detect and configure AST tools for T1 confidence."
90
137
 
91
- Degrade to Quick tier extraction. Note the degradation reason in context for the evidence report.
138
+ Degrade to Quick tier extraction, and append a `workflow_warnings[]` entry (`step: "step-04"`, `severity: "warn"`, `code: "ast-degraded"`, `message`: the tier and the reason), which the evidence report lists.
92
139
 
93
140
  **Per-file AST failure handling:**
94
141
 
95
- If ast-grep fails on an individual file (parse error, unsupported syntax), fall back to source reading for that file only. Label the affected file's results T1-low; unaffected files retain T1. Log a warning noting which file degraded and why.
142
+ If ast-grep fails on an individual file (parse error, unsupported syntax), fall back to source reading for that file only, and log a warning noting which file degraded and why.
96
143
 
97
144
  For each library in `confirmed_dependencies`, determine extraction strategy based on forge tier:
98
145
 
@@ -100,16 +147,14 @@ For each library in `confirmed_dependencies`, determine extraction strategy base
100
147
  - Read source files that import the library
101
148
  - Extract usage patterns from import statements and function calls
102
149
  - Identify key exports used in this project
103
- - Confidence: T1-low (source reading inference)
104
150
 
105
151
  **Forge Tier (adds to Quick):**
106
152
  - Use ast_bridge to analyze structural exports from library source
107
153
  - Extract function signatures, type definitions, class hierarchies
108
154
  - Map parameter types and return types
109
- - Confidence: T1 (AST-verified structural extraction)
110
155
 
111
156
  **Deep Tier (adds to Forge):**
112
- - Perform all Forge tier extractions (T1)
157
+ - Perform all Forge tier extractions
113
158
  - Additionally: query existing QMD temporal collections for each library
114
159
  - Read the `qmd_collections` registry from `{sidecar_path}/forge-tier.yaml`
115
160
  - For each library in `confirmed_dependencies`, search for a registry entry where `skill_name` matches the library name AND `type` is `"temporal"`
@@ -123,26 +168,36 @@ For each library in `confirmed_dependencies`, determine extraction strategy base
123
168
  - **If no matching temporal collection found:**
124
169
  - Log: "No temporal collection for {library_name}. T2 enrichment skipped."
125
170
  - Continue with T1/T1-low extraction only
126
- - Confidence: T1 for structural (AST), T2 for temporal annotations (QMD-enriched)
127
171
 
128
172
  ### 2. Launch Parallel Extraction
129
173
 
130
174
  **Launch subprocesses in parallel** (max_parallel_generation: 3–5 concurrent Agent tool calls in Claude Code, IDE-dependent in Cursor, CPU core count in CLI) — one per confirmed library:
131
175
 
132
176
  Each subprocess:
133
- 1. Reads all files importing the library (from step 03 file lists)
177
+ 1. Reads all files importing the library (its `files[]` in `{importCountsFile}`, step 3's import counts, whose paths are relative to `{project_root}`, as `source_file` is)
134
178
  2. Extracts key exports used in this project (functions, classes, types, constants)
135
179
  3. Identifies usage patterns (initialization, configuration, common call patterns)
136
- 4. Labels confidence tier based on extraction method
137
- 5. Returns structured extraction to parent:
180
+ 4. Labels each export by the tool that read it (§1)
181
+ 5. Returns structured extraction to parent, one record per export:
138
182
 
139
183
  ```
140
184
  {
141
185
  library: "name",
142
186
  version: "from_manifest",
143
- exports_found: ["fn1", "fn2", "Type1"],
187
+ exports: [
188
+ {
189
+ export_name: "fn1",
190
+ export_type: "function|class|type|constant",
191
+ params: ["typed param strings"],
192
+ return_type: "type",
193
+ source_file: "path relative to {project_root}",
194
+ source_line: 0,
195
+ extraction_method: "ast_bridge|source_reading",
196
+ confidence: "T1|T1-low",
197
+ signature_source: "T1|T1-low"
198
+ }
199
+ ],
144
200
  usage_patterns: ["pattern description with file:line"],
145
- confidence: "T1|T1-low|T2|T3",
146
201
  files_analyzed: count,
147
202
  warnings: [],
148
203
  temporal: {
@@ -154,6 +209,8 @@ Each subprocess:
154
209
  }
155
210
  ```
156
211
 
212
+ `{project_root}` is the project root, `project_root` from step 1, whatever folder `{scan_root}` narrowed steps 2, 3 and 5 to: `source_file` is relative to it, with forward slashes (a library installed outside it, in a global site-packages say, is relative to its install folder, and step 7 warns on it). `source_line` is the export's `def`, `class` or declaration line, not a decorator above it. The subprocess returns no library tier: §3a sets it.
213
+
157
214
  **If parallel subprocess unavailable:** Process libraries sequentially in main thread. Report progress after each library.
158
215
 
159
216
  **Per-subprocess timeout (S6):** Apply a 60-second wall-clock timeout to each library's extraction subprocess. On timeout, mark the library as `partial-failure` with `warnings: ["extraction timeout after 60s"]`, store whatever partial data was returned (if any), and continue with the remaining libraries. Do NOT abort the batch on a single timeout.
@@ -162,7 +219,7 @@ Each subprocess:
162
219
 
163
220
  For each library extraction:
164
221
 
165
- **Success:** Store extraction result.
222
+ **Success:** Store the extraction result as the library's `per_library_extractions[]` entry.
166
223
 
167
224
  **Partial failure:** Store partial result with warnings, continue with other libraries.
168
225
 
@@ -170,18 +227,35 @@ For each library extraction:
170
227
 
171
228
  "**Warning:** Extraction failed for {library}: {reason}. Excluding from stack skill."
172
229
 
173
- **If ALL extractions fail:** HALT — cannot produce meaningful stack skill. Before halting (B7):
230
+ Record each excluded library in the bundle's `failed[]` and append a `workflow_warnings[]` entry (`step: "step-04"`, `severity: "warn"`, `code: "extraction-failed"`, `message`: the library and the reason).
231
+
232
+ **If ALL extractions fail:** HALT (exit 2, `halt_reason: "all-extractions-failed"`, phase `parallel-extract:all-failed`, `stack_libraries` the confirmed library names that failed): nothing remains to build a stack from (B7). The run folder stays, as after every halt but a cancel: its `warnings.jsonl` holds the `extraction-failed` entry that says why each library failed.
233
+
234
+ **Otherwise** write `{bundleFile}`: `mode`, `scope`, one `per_library_extractions[]` entry per library that returned (each export record moves to `{exportRecordsFile}` in §3a, so the entry keeps none) and `failed[]`.
235
+
236
+ ### 3a. Check the Export Labels
174
237
 
175
- 1. Purge any in-flight staging artifacts under the forge workspace: remove `{forge_data_folder}/{project_name}-stack/{version}/*-tmp` and any `{forge_data_folder}/{project_name}-stack/{version}/*.skf-tmp` directories so partial state does not linger.
176
- 2. Emit the result envelope on stderr per the Result Contract in SKILL.md (`stack_libraries` carries the confirmed library names that failed extraction), and exit `2`:
238
+ Code mode only (compose mode leaves this step at §0). Steps 5 to 7 read the labels checked here, from the file this section writes and keeps for the rest of the run.
239
+
240
+ Write every export record, each with `source_library` set to its library, as `{"entries": [...]}` to `{exportRecordsFile}`. Resolve `{renderStackMetadataHelper}` from `{renderStackMetadataProbeOrder}`; first existing path wins. If no candidate exists, HALT (exit 3, `halt_reason: "helper-missing"`, phase `parallel-extract:library-tiers`) with "**Cannot proceed.** `skf-render-stack-metadata.py` is missing, so no export label can be checked and no library tier set. Re-install SKF, then re-run." Otherwise relabel the records:
241
+
242
+ ```bash
243
+ uv run {renderStackMetadataHelper} relabel --records "{exportRecordsFile}"
244
+ ```
245
+
246
+ Keep its `confidence_distribution` (one count per record, never `metadata.json`'s) as §4's export label counts. When its `relabeled[]` is not empty, append one `workflow_warnings[]` entry (`step: "step-04"`, `severity: "info"`, `code: "export-labels-relabeled"`) naming each relabeled export and its library. When it exits `1` (a violation it could not fix, in its `coherence.violations[]`) or `2` (no JSON: its stderr says why), append a `workflow_warnings[]` entry (`step: "step-04"`, `severity: "warn"`, `code: "label-check-skipped"`, `message`: those violations or its stderr) and go on.
247
+
248
+ **Library tiers.** Run the same helper on the checked records, with every library of the bundle's `per_library_extractions[]`, comma-separated:
249
+
250
+ ```bash
251
+ uv run {renderStackMetadataHelper} library-tiers --records "{exportRecordsFile}" --libraries "<names>"
252
+ ```
177
253
 
178
- ```
179
- SKF_STACK_RESULT_JSON: {"status":"error","skill_package":null,"skill_name":"{project_name}-stack","stack_libraries":["<confirmed-lib>", "..."],"mode":"{code|compose}","exit_code":2,"halt_reason":"all-extractions-failed"}
180
- ```
254
+ Set each library's `per_library_extractions[].confidence` in `{bundleFile}` to its `tier`, the helper's one rule for a code-mode library. On exit `2` its stderr names the input it refused, such as a record whose `source_library` is not a stack library: fix the record or the list and run it again. Step 5 takes each integration's tier from these tiers, and step 7 bins each library once by them.
181
255
 
182
256
  ### 4. Display Extraction Summary
183
257
 
184
- Report the extraction results: per library the export count, pattern count, confidence tier, and success/partial status; the overall `{success_count}/{total_count}` extracted; and the T1 / T1-low / T2 confidence distribution. At Deep tier, add the T2-enrichment count (`{enriched_count}/{total_count}` libraries with temporal collections available); and if any library lacked a temporal collection, add the tip: run **[CS] Create Skill** at Deep tier for those libraries to generate temporal collections, then re-run **[SS]** for full T2 enrichment. Note any warning count.
258
+ Report the extraction results from `{bundleFile}`: per library the export count, pattern count, confidence tier, and success/partial status; the overall `{success_count}/{total_count}` extracted; the number of libraries at each tier (the unit of `metadata.json`'s `confidence_distribution`); and the export label counts §3a kept. At Deep tier, add the T2-enrichment count (`{enriched_count}/{total_count}` libraries with temporal collections available); and if any library lacked a temporal collection, add the tip: run **[CS] Create Skill** at Deep tier for those libraries to generate temporal collections, then re-run **[SS]** for full T2 enrichment. Note any warning count.
185
259
 
186
260
  ### 5. Auto-Proceed to Next Step
187
261
 
@@ -1,5 +1,12 @@
1
1
  ---
2
2
  nextStepFile: 'parallel-extract.md'
3
+ countImportsProbeOrder:
4
+ - '{project-root}/_bmad/skf/shared/scripts/skf-count-imports.py'
5
+ - '{project-root}/src/shared/scripts/skf-count-imports.py'
6
+ emitEnvelopeProbeOrder:
7
+ - '{project-root}/_bmad/skf/shared/scripts/skf-emit-result-envelope.py'
8
+ - '{project-root}/src/shared/scripts/skf-emit-result-envelope.py'
9
+ importCountsFile: '{run_dir}/import-counts.json'
3
10
  ---
4
11
 
5
12
  <!-- Config: communicate in {communication_language}. -->
@@ -8,26 +15,34 @@ nextStepFile: 'parallel-extract.md'
8
15
 
9
16
  ## STEP GOAL:
10
17
 
11
- Count import frequency for each dependency across the codebase, rank by usage, and present for user confirmation of which libraries to include in the stack skill.
18
+ Count the files under `{scan_root}` that import each dependency, rank by usage, and confirm at one gate which libraries the stack skill includes.
12
19
 
13
20
  ## Rules
14
21
 
15
22
  - Focus on counting imports, ranking, and getting user confirmation — do not extract documentation (Step 04)
16
- - Use subprocess Pattern 1 (grep/search) when available
23
+ - Take every count from `skf-count-imports.py`; never count imports by hand
17
24
 
18
25
  ## MANDATORY SEQUENCE
19
26
 
27
+ **Halt envelope.** Every 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}", "mode": "<code|compose>"}`, then run:
28
+
29
+ ```bash
30
+ uv run {emitEnvelopeHelper} emit-halt --workflow skf-create-stack-skill --run-dir "{run_dir}" --target stderr < "{run_dir}/halt.json"
31
+ ```
32
+
33
+ Display the line it prints, then stop with the halt's exit code (`references/invocation-contract.md` lists every halt). If `{emitEnvelopeHelper}` is not bound, resolve it from `{emitEnvelopeProbeOrder}`; if no path exists, or the emitter exits non-zero or prints no line, display the halt message alone.
34
+
35
+ **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")"`.
36
+
20
37
  ### 1. Count Import Frequency
21
38
 
22
39
  **If `compose_mode` is true:**
23
40
 
24
- Skip import counting entirely. All skills are included by default.
25
-
26
- Set `confirmed_dependencies` = all `raw_dependencies` (the list already stored as workflow state from Step 02).
41
+ Skip import counting entirely. All skills are included by default: the recommended scope is every `raw_dependencies` entry (the list step 2 stored).
27
42
 
28
43
  **Apply scope_overrides:** If `scope_overrides` were provided in step 01, apply them now — force-include or force-exclude skills as specified. Log any overrides applied.
29
44
 
30
- **Validate override keys (S4):** Every key in `scope_overrides` MUST be present in `raw_dependencies`. For any unknown key, emit `"scope_override: unknown dependency '{key}' — skipping"` and drop that override entry (do not fail the run). Known-key overrides still apply.
45
+ **Validate override keys (S4):** Every key in `scope_overrides` MUST be present in `raw_dependencies`. For any unknown key, append a `workflow_warnings[]` entry (`step: "step-03"`, `severity: "warn"`, `code: "scope-override-unknown"`, `message`: "scope_override: unknown dependency '{key}', skipped") and drop that override entry (do not fail the run). Known-key overrides still apply.
31
46
 
32
47
  Present skills sorted by architectural layer (from architecture doc if available):
33
48
  - If `architecture_doc_path` is not null: **wrap the architecture-doc parse in try/except (S5)**. On any parse error (file unreadable, malformed markdown, no H2 structure), fall back to alphabetical ordering and log a warning `"architecture-doc parse failed: {error} — falling back to alphabetical"`. Otherwise parse section headers to determine layer grouping.
@@ -39,100 +54,67 @@ Display skills as a table:
39
54
  |---|-------|----------|------|--------------------|
40
55
  | 1 | {name} | {language} | {confidence_tier} | {layer or 'Unclassified'} |
41
56
 
42
- User confirms inclusion/exclusion at the gate (same [C] menu as code-mode).
43
-
44
- Skip to [Present MENU OPTIONS](#5-present-menu-options).
57
+ Set `confirmed_dependencies` ← that scope, with the overrides applied, and skip to [Confirm the Scope](#3-confirm-the-scope).
45
58
 
46
59
  **If not compose_mode:**
47
60
 
48
- For each dependency in `raw_dependencies`:
61
+ Count, for each dependency, the files under `{scan_root}` that import it, with the shared helper that holds the counting rules (its `--help` states them). **Resolve `{countImportsHelper}`** from `{countImportsProbeOrder}`; first existing path wins. If no candidate exists, HALT (exit 3, `halt_reason: "helper-missing"`, phase `rank-and-confirm:count`) with "**Cannot proceed.** `skf-count-imports.py` is missing, so no import can be counted. Re-install SKF, then re-run."
49
62
 
50
- **Launch a subprocess** that runs grep across all source files in the project to count import statements for each library. Return only the counts, not file contents.
63
+ ```bash
64
+ uv run {countImportsHelper} count {scan_root} --deps - --relative-to {project_root} > "{importCountsFile}"
65
+ ```
51
66
 
52
- **Subprocess resolution:** Use the Grep tool (Claude Code), built-in search (Cursor), or `grep`/`rg` (CLI). See `knowledge/tool-resolution.md`.
67
+ Pipe `raw_dependencies` on stdin: step 2's scan JSON as it stands, or, when step 2 took `explicit_deps`, those names as a JSON array (if stdin piping is unavailable, write it to `{run_dir}/dependencies.json` and pass that path to `--deps`). `{project_root}` is `project_root` from step 1: the helper scans only `{scan_root}` and writes each path relative to the project root, the base every path this run records shares. Its JSON goes to `{importCountsFile}`, the run's import counts, which this step ranks from: step 4 reads each library's files from it, and step 5 §1 passes it to the pair helper as it stands. Each `dependencies[]` entry gives `file_count`, `files[]` (`path`, and `line`, the first line that imports it) and `above_threshold` (2 or more files); a dependency only the dev sections list carries `scope: "dev"`.
53
68
 
54
- Use ecosystem-appropriate import patterns:
55
- - JavaScript/TypeScript: `import .* from ['"]library`, `require\(['"]library`
56
- - Python: `import library`, `from library import`
57
- - Rust: `use library::`, `extern crate library`
58
- - Go: `"library"` in import blocks
59
- - (Match patterns from `{manifestPatternsPath}`)
60
-
61
- **Subprocess returns:** `{library_name: import_count, files: [file_paths]}` for each dependency.
62
-
63
- **If subprocess unavailable:** Perform grep operations in main thread sequentially.
64
-
65
- Exclude from counting:
66
- - Test files (*/test/*, *_test.*, *.spec.*, *.test.*)
67
- - Config files (*.config.*, .eslintrc, etc.)
68
- - Build artifacts (dist/, build/, node_modules/, target/, __pycache__/)
69
+ **Unresolved names.** `unresolved[]` lists, each with its `reason`, the dependencies the helper cannot count with confidence: a guessed import name that matched no file, no import name, or an ecosystem with no import rules; the helper never counts them as 0. For a runtime entry whose import name you know (`python-dateutil` is imported as `dateutil`), run the call again with that name and without the `>` redirect, which would replace the file, piping `[{"name": "<name>", "ecosystem": "<its ecosystem>", "modules": ["<import name>"]}]`, add the `dependencies[]` entry it returns to `{importCountsFile}`, drop the entry from `unresolved[]`, keep `dependencies[]` sorted by `file_count` (highest first), then name, and write the file back, so the library ranks and pairs like the others. Every other unresolved entry goes below the threshold with its `reason`.
69
70
 
70
71
  ### 2. Rank and Filter
71
72
 
72
- Sort dependencies by import count (descending).
73
+ `dependencies[]` comes ranked: by `file_count`, highest first, then by name.
73
74
 
74
75
  Apply filtering:
75
- - **Include by default:** Libraries with 2+ import files
76
- - **Flag as trivial:** Libraries with 0-1 import files
76
+ - **Include by default:** the runtime libraries with `above_threshold` true
77
+ - **Below threshold:** every other library: under 2 files, a dev-only dependency, or an unresolved one
77
78
  - **Apply scope_overrides** from step 01 if provided (force include/exclude)
78
79
 
79
- ### 3. Present Ranked List
80
-
81
- "**Dependency ranking complete.** Here are your project's libraries ranked by usage:
80
+ Set `confirmed_dependencies` ← the recommended scope: the libraries included by default, with the overrides applied. The gate below keeps it, or the user's edits change it.
82
81
 
83
- | # | Library | Imports | Files | Category |
84
- |---|---------|---------|-------|----------|
85
- | 1 | {name} | {count} | {file_count} | runtime |
86
- | 2 | {name} | {count} | {file_count} | runtime |
87
- | ... | ... | ... | ... | ... |
82
+ ### 3. Confirm the Scope
88
83
 
89
- **Below threshold** (0-1 imports — excluded by default):
90
- | Library | Imports | Category |
91
- |---------|---------|----------|
92
- | {name} | {count} | {category} |
84
+ Present the scope and the one gate. **In code mode:**
93
85
 
94
- **Total:** {total} dependencies detected, {above_threshold} recommended for inclusion
95
-
96
- ---
97
-
98
- **Please confirm your scope:**
99
- - Type **C** to accept the recommended scope (all above-threshold libraries)
100
- - Type library names to **add** from the below-threshold list
101
- - Type **-library_name** to **exclude** a recommended library
102
- - Type a custom list to override entirely"
103
-
104
- ### 4. Process User Response
105
-
106
- **If C (accept recommended):**
107
- Store all above-threshold libraries as `confirmed_dependencies`.
86
+ "**Dependency ranking complete.** Here are your project's libraries ranked by usage:
108
87
 
109
- **If modifications requested:**
110
- Apply additions/exclusions, display updated list, and ask for final confirmation.
88
+ | # | Library | Files | Category |
89
+ |---|---------|-------|----------|
90
+ | 1 | {name} | {file_count} | runtime |
91
+ | 2 | {name} | {file_count} | runtime |
92
+ | ... | ... | ... | ... |
111
93
 
112
- **If custom list provided:**
113
- Use the custom list as `confirmed_dependencies`.
94
+ **Below threshold** (excluded by default):
95
+ | Library | Files | Category |
96
+ |---------|-------|----------|
97
+ | {name} | {file_count, or the unresolved `reason`} | {runtime, or dev for a `scope: "dev"` dependency} |
114
98
 
115
- Display the resolved scope:
99
+ **Total:** {total} dependencies detected, {above_threshold} recommended for inclusion"
116
100
 
117
- "**Scope confirmed:** {count} libraries selected for stack skill extraction.
101
+ **In compose mode** the skills table of §1 is the scope.
118
102
 
119
- {List confirmed libraries}"
103
+ Display: **Select:** [C] Continue to extraction with this scope | [X] Cancel and exit, or type library names to **add** from the below-threshold list, **-library_name** to **exclude** one, or a custom list to replace the scope.
120
104
 
121
- The extraction itself begins only once the user clears the gate below.
105
+ #### EXECUTION RULES:
122
106
 
123
- ### 5. Present MENU OPTIONS
107
+ - This is a confirmation gate: advancing without the user's `C` would extract and ship a stack scope they never approved. Halt and wait for input after presenting the scope.
108
+ - **GATE [default: C]**: If `{headless_mode}`: auto-proceed with [C] Continue, keeping `confirmed_dependencies` as §2 set it (the recommended libraries in code mode, every skill in compose mode), and record the auto-decision, which names each library the default left out: stage `{"gate": "rank-and-confirm.scope", "default_action": "C", "taken_action": "C", "reason": "headless: kept the recommended scope", "evidence": {"scope": ["<confirmed library>", ...], "dropped": [{"library": "<name>", "reason": "<under 2 files, dev only, its unresolved reason, or excluded by scope_overrides>"}, ...]}}` as `{run_dir}/decision.json` and run:
124
109
 
125
- Display: **Select:** [C] Continue to Extraction | [X] Cancel and exit
110
+ ```bash
111
+ uv run {emitEnvelopeHelper} record --workflow skf-create-stack-skill --run-dir "{run_dir}" --decision < "{run_dir}/decision.json"
112
+ ```
126
113
 
127
- #### EXECUTION RULES:
128
-
129
- - This is a confirmation gate — advancing without the user's `C` would extract and ship a stack scope they never approved. Halt and wait for input after presenting scope.
130
- - **GATE [default: C]** — If `{headless_mode}`: auto-proceed with [C] Continue (accept all ranked libraries), log: "headless: auto-confirm library scope"
131
- - Proceed to the next step only once the user confirms scope by selecting `C`.
114
+ - Proceed to the next step only once the user approves the scope by selecting `C`.
132
115
 
133
116
  #### Menu Handling Logic:
134
117
 
135
- - IF C: Store current `confirmed_dependencies` (including any modifications made since initial presentation), then load, read entire file, then execute {nextStepFile}
136
- - IF X: Invoke the rollback contract (purge any `{forge_data_folder}/{project_name}-stack/{version}/*-tmp` and `*.skf-tmp` staging artifacts under the forge workspace, leave any existing committed stack package untouched), emit the `SKF_STACK_RESULT_JSON` envelope on stderr with `status: "error"`, `halt_reason: "user-cancelled"`, `exit_code: 6`, and exit with code 6
137
- - IF Any other: Process as scope modification (add/remove skills from `confirmed_dependencies`), update the in-memory `confirmed_dependencies` list accordingly, redisplay the updated skills table, then [Redisplay Menu Options](#5-present-menu-options)
138
-
118
+ - IF C: Display "**Scope confirmed:** {count} libraries selected for stack skill extraction." with the list, then load, read entire file, then execute {nextStepFile}
119
+ - IF X: HALT (exit 6, `halt_reason: "user-cancelled"`, phase `rank-and-confirm:scope`): leave any existing committed stack package untouched, emit the envelope, then delete the run folder (`rm -rf "{run_dir}"`)
120
+ - IF Any other: Process it as a scope change (add or remove libraries from `confirmed_dependencies`, or replace them with a custom list), redisplay the updated table, then [Redisplay the gate](#3-confirm-the-scope)