bmad-module-skill-forge 1.4.0 → 1.5.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 (231) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/README.md +0 -8
  3. package/docs/_data/pinned.yaml +1 -1
  4. package/docs/_internal/STABILITY.md +1 -1
  5. package/docs/architecture.md +2 -2
  6. package/docs/examples.md +1 -1
  7. package/docs/workflows.md +5 -5
  8. package/package.json +2 -2
  9. package/src/README.md +1 -1
  10. package/src/knowledge/ccc-bridge.md +12 -12
  11. package/src/knowledge/qmd-registry.md +5 -5
  12. package/src/shared/health-check.md +5 -5
  13. package/src/shared/references/description-guard-protocol.md +100 -0
  14. package/src/shared/references/output-contract-schema.md +1 -1
  15. package/src/shared/scripts/schemas/skf-brief-result-envelope.v1.json +6 -6
  16. package/src/shared/scripts/schemas/skf-setup-result-envelope.v1.json +9 -3
  17. package/src/shared/scripts/schemas/skf-update-result-envelope.v1.json +149 -0
  18. package/src/shared/scripts/schemas/skill-brief.v1.json +22 -2
  19. package/src/shared/scripts/skf-build-change-manifest.py +420 -0
  20. package/src/shared/scripts/skf-check-workspace-drift.py +321 -0
  21. package/src/shared/scripts/skf-compare-file-hashes.py +357 -0
  22. package/src/shared/scripts/skf-description-guard.py +359 -0
  23. package/src/shared/scripts/skf-detect-language.py +2 -2
  24. package/src/shared/scripts/skf-detect-scripts-assets.py +613 -0
  25. package/src/shared/scripts/skf-detect-tools.py +97 -8
  26. package/src/shared/scripts/skf-detect-workspaces.py +1 -1
  27. package/src/shared/scripts/skf-disqualify-candidates.py +576 -0
  28. package/src/shared/scripts/skf-emit-brief-result-envelope.py +3 -3
  29. package/src/shared/scripts/skf-emit-result-envelope.py +93 -9
  30. package/src/shared/scripts/skf-enumerate-stack-skills.py +514 -0
  31. package/src/shared/scripts/skf-forge-tier-rw.py +11 -11
  32. package/src/shared/scripts/skf-hash-content.py +284 -0
  33. package/src/shared/scripts/skf-load-provenance.py +295 -0
  34. package/src/shared/scripts/skf-merge-ccc-exclusions.py +45 -1
  35. package/src/shared/scripts/skf-pair-intersect.py +250 -0
  36. package/src/shared/scripts/skf-provenance-gap-dispatch.py +433 -0
  37. package/src/shared/scripts/skf-qmd-classify-collections.py +42 -8
  38. package/src/shared/scripts/skf-recommend-scope-type.py +2 -2
  39. package/src/shared/scripts/skf-render-quick-metadata.py +2 -2
  40. package/src/shared/scripts/skf-resolve-authoritative-files.py +504 -0
  41. package/src/shared/scripts/skf-scan-manifests.py +738 -0
  42. package/src/shared/scripts/skf-scan-skill-md-structure.py +375 -0
  43. package/src/shared/scripts/skf-update-active-symlink.py +315 -0
  44. package/src/shared/scripts/skf-validate-brief-inputs.py +5 -5
  45. package/src/shared/scripts/skf-validate-brief-schema.py +348 -0
  46. package/src/shared/scripts/skf-write-skill-brief.py +61 -5
  47. package/src/skf-analyze-source/SKILL.md +69 -16
  48. package/src/skf-analyze-source/assets/skill-brief-schema.md +1 -1
  49. package/src/skf-analyze-source/customize.toml +55 -0
  50. package/src/skf-analyze-source/{steps-c/step-01b-continue.md → references/continue.md} +12 -12
  51. package/src/skf-analyze-source/{steps-c/step-06-generate-briefs.md → references/generate-briefs.md} +29 -10
  52. package/src/skf-analyze-source/{steps-c/step-07-health-check.md → references/health-check.md} +5 -3
  53. package/src/skf-analyze-source/{steps-c/step-03-identify-units.md → references/identify-units.md} +44 -14
  54. package/src/skf-analyze-source/{steps-c/step-01-init.md → references/init.md} +27 -6
  55. package/src/skf-analyze-source/{steps-c/step-04-map-and-detect.md → references/map-and-detect.md} +52 -25
  56. package/src/skf-analyze-source/{steps-c/step-05-recommend.md → references/recommend.md} +15 -8
  57. package/src/skf-analyze-source/{steps-c/step-02-scan-project.md → references/scan-project.md} +12 -10
  58. package/src/skf-analyze-source/references/unit-detection-heuristics.md +2 -0
  59. package/src/skf-analyze-source/templates/analysis-report-template.md +6 -6
  60. package/src/skf-audit-skill/SKILL.md +66 -15
  61. package/src/skf-audit-skill/assets/drift-report-template.md +6 -5
  62. package/src/skf-audit-skill/customize.toml +49 -0
  63. package/src/skf-audit-skill/{steps-c/step-07-health-check.md → references/health-check.md} +5 -3
  64. package/src/skf-audit-skill/references/init.md +305 -0
  65. package/src/skf-audit-skill/{steps-c/step-02-re-index.md → references/re-index.md} +11 -11
  66. package/src/skf-audit-skill/{steps-c/step-06-report.md → references/report.md} +25 -7
  67. package/src/skf-audit-skill/{steps-c/step-04-semantic-diff.md → references/semantic-diff.md} +6 -6
  68. package/src/skf-audit-skill/{steps-c/step-05-severity-classify.md → references/severity-classify.md} +5 -5
  69. package/src/skf-audit-skill/references/severity-rules.md +2 -0
  70. package/src/skf-audit-skill/{steps-c/step-03-structural-diff.md → references/structural-diff.md} +29 -16
  71. package/src/skf-brief-skill/SKILL.md +48 -18
  72. package/src/skf-brief-skill/assets/description-voice-examples.md +1 -1
  73. package/src/skf-brief-skill/assets/skill-brief-schema.md +32 -2
  74. package/src/skf-brief-skill/customize.toml +44 -0
  75. package/src/skf-brief-skill/{steps-c/step-02-analyze-target.md → references/analyze-target.md} +5 -5
  76. package/src/skf-brief-skill/{steps-c/step-04-confirm-brief.md → references/confirm-brief.md} +13 -10
  77. package/src/skf-brief-skill/references/draft-checkpoint.md +4 -4
  78. package/src/skf-brief-skill/{steps-c/step-01-gather-intent.md → references/gather-intent.md} +24 -24
  79. package/src/skf-brief-skill/references/headless-args.md +9 -9
  80. package/src/skf-brief-skill/references/headless-source-authority-detection.md +1 -1
  81. package/src/skf-brief-skill/{steps-c/step-06-health-check.md → references/health-check.md} +4 -2
  82. package/src/skf-brief-skill/references/portfolio-similarity-check.md +2 -2
  83. package/src/skf-brief-skill/references/qmd-collection-registration.md +1 -1
  84. package/src/skf-brief-skill/{steps-c/step-03-scope-definition.md → references/scope-definition.md} +19 -16
  85. package/src/skf-brief-skill/references/version-resolution.md +2 -2
  86. package/src/skf-brief-skill/{steps-c/step-05-write-brief.md → references/write-brief.md} +11 -10
  87. package/src/skf-create-skill/SKILL.md +25 -19
  88. package/src/skf-create-skill/assets/compile-assembly-rules.md +3 -3
  89. package/src/skf-create-skill/assets/skill-sections.md +5 -5
  90. package/src/skf-create-skill/assets/tessl-dismissal-rules.md +11 -11
  91. package/src/skf-create-skill/customize.toml +35 -0
  92. package/src/skf-create-skill/references/authoritative-files-protocol.md +142 -0
  93. package/src/skf-create-skill/{steps-c/step-05-compile.md → references/compile.md} +16 -16
  94. package/src/skf-create-skill/{steps-c/step-03d-component-extraction.md → references/component-extraction.md} +16 -16
  95. package/src/skf-create-skill/{steps-c/step-02-ecosystem-check.md → references/ecosystem-check.md} +4 -4
  96. package/src/skf-create-skill/{steps-c/step-04-enrich.md → references/enrich.md} +3 -3
  97. package/src/skf-create-skill/{steps-c/step-03-extract.md → references/extract.md} +52 -120
  98. package/src/skf-create-skill/references/extraction-patterns.md +8 -8
  99. package/src/skf-create-skill/{steps-c/step-07-generate-artifacts.md → references/generate-artifacts.md} +17 -9
  100. package/src/skf-create-skill/{steps-c/step-09-health-check.md → references/health-check.md} +4 -2
  101. package/src/skf-create-skill/{steps-c/step-01-load-brief.md → references/load-brief.md} +40 -32
  102. package/src/skf-create-skill/{steps-c/step-08-report.md → references/report.md} +8 -8
  103. package/src/skf-create-skill/references/source-resolution-protocols.md +6 -6
  104. package/src/skf-create-skill/{steps-c/sub/step-02b-ccc-discover.md → references/sub/ccc-discover.md} +5 -5
  105. package/src/skf-create-skill/{steps-c/sub/step-03c-fetch-docs.md → references/sub/fetch-docs.md} +28 -12
  106. package/src/skf-create-skill/{steps-c/sub/step-03b-fetch-temporal.md → references/sub/fetch-temporal.md} +81 -50
  107. package/src/skf-create-skill/{steps-c/step-06-validate.md → references/validate.md} +46 -26
  108. package/src/skf-create-stack-skill/SKILL.md +76 -17
  109. package/src/skf-create-stack-skill/assets/provenance-map-schema.md +102 -0
  110. package/src/skf-create-stack-skill/assets/stack-skill-template.md +1 -1
  111. package/src/skf-create-stack-skill/customize.toml +46 -0
  112. package/src/skf-create-stack-skill/{steps-c/step-06-compile-stack.md → references/compile-stack.md} +6 -5
  113. package/src/skf-create-stack-skill/references/compose-mode-rules.md +3 -1
  114. package/src/skf-create-stack-skill/{steps-c/step-05-detect-integrations.md → references/detect-integrations.md} +32 -11
  115. package/src/skf-create-stack-skill/{steps-c/step-02-detect-manifests.md → references/detect-manifests.md} +28 -28
  116. package/src/skf-create-stack-skill/{steps-c/step-07-generate-output.md → references/generate-output.md} +11 -85
  117. package/src/skf-create-stack-skill/{steps-c/step-10-health-check.md → references/health-check.md} +4 -2
  118. package/src/skf-create-stack-skill/{steps-c/step-01-init.md → references/init.md} +70 -4
  119. package/src/skf-create-stack-skill/references/integration-patterns.md +2 -0
  120. package/src/skf-create-stack-skill/references/manifest-patterns.md +2 -0
  121. package/src/skf-create-stack-skill/{steps-c/step-04-parallel-extract.md → references/parallel-extract.md} +40 -17
  122. package/src/skf-create-stack-skill/{steps-c/step-03-rank-and-confirm.md → references/rank-and-confirm.md} +5 -4
  123. package/src/skf-create-stack-skill/{steps-c/step-09-report.md → references/report.md} +3 -3
  124. package/src/skf-create-stack-skill/{steps-c/step-08-validate.md → references/validate.md} +6 -6
  125. package/src/skf-drop-skill/SKILL.md +84 -12
  126. package/src/skf-drop-skill/customize.toml +57 -0
  127. package/src/skf-drop-skill/{steps-c/step-02-execute.md → references/execute.md} +49 -34
  128. package/src/skf-drop-skill/{steps-c/step-04-health-check.md → references/health-check.md} +6 -4
  129. package/src/skf-drop-skill/{steps-c/step-03-report.md → references/report.md} +13 -5
  130. package/src/skf-drop-skill/{steps-c/step-01-select.md → references/select.md} +63 -15
  131. package/src/skf-export-skill/SKILL.md +85 -16
  132. package/src/skf-export-skill/assets/managed-section-format.md +3 -3
  133. package/src/skf-export-skill/assets/snippet-format.md +2 -2
  134. package/src/skf-export-skill/customize.toml +49 -0
  135. package/src/skf-export-skill/{steps-c/step-03-generate-snippet.md → references/generate-snippet.md} +18 -12
  136. package/src/skf-export-skill/{steps-c/step-07-health-check.md → references/health-check.md} +6 -4
  137. package/src/skf-export-skill/{steps-c/step-01-load-skill.md → references/load-skill.md} +21 -51
  138. package/src/skf-export-skill/references/manifest-rebuild.md +68 -0
  139. package/src/skf-export-skill/references/multi-skill-mode.md +38 -0
  140. package/src/skf-export-skill/references/orphan-context-detection.md +75 -0
  141. package/src/skf-export-skill/references/orphan-row-detection.md +102 -0
  142. package/src/skf-export-skill/{steps-c/step-02-package.md → references/package.md} +7 -7
  143. package/src/skf-export-skill/references/preflight-snippet-root-probe.md +74 -0
  144. package/src/skf-export-skill/{steps-c/step-06-summary.md → references/summary.md} +30 -6
  145. package/src/skf-export-skill/{steps-c/step-05-token-report.md → references/token-report.md} +5 -5
  146. package/src/skf-export-skill/{steps-c/step-04-update-context.md → references/update-context.md} +116 -91
  147. package/src/skf-quick-skill/SKILL.md +63 -123
  148. package/src/skf-quick-skill/customize.toml +44 -0
  149. package/src/skf-quick-skill/references/batch-mode.md +102 -0
  150. package/src/skf-quick-skill/{steps-c/step-04-compile.md → references/compile.md} +10 -10
  151. package/src/skf-quick-skill/{steps-c/step-02-ecosystem-check.md → references/ecosystem-check.md} +5 -5
  152. package/src/skf-quick-skill/{steps-c/step-06-finalize.md → references/finalize.md} +7 -7
  153. package/src/skf-quick-skill/{steps-c/step-07-health-check.md → references/health-check.md} +3 -3
  154. package/src/skf-quick-skill/{steps-c/step-03-quick-extract.md → references/quick-extract.md} +5 -5
  155. package/src/skf-quick-skill/references/registry-resolution.md +2 -0
  156. package/src/skf-quick-skill/{steps-c/step-01-resolve-target.md → references/resolve-target.md} +14 -10
  157. package/src/skf-quick-skill/{steps-c/step-05-write-and-validate.md → references/write-and-validate.md} +4 -4
  158. package/src/skf-refine-architecture/SKILL.md +86 -16
  159. package/src/skf-refine-architecture/customize.toml +49 -0
  160. package/src/skf-refine-architecture/{steps-c/step-05-compile.md → references/compile.md} +4 -4
  161. package/src/skf-refine-architecture/{steps-c/step-02-gap-analysis.md → references/gap-analysis.md} +5 -5
  162. package/src/skf-refine-architecture/{steps-c/step-07-health-check.md → references/health-check.md} +6 -4
  163. package/src/skf-refine-architecture/{steps-c/step-04-improvements.md → references/improvements.md} +5 -5
  164. package/src/skf-refine-architecture/references/init.md +144 -0
  165. package/src/skf-refine-architecture/{steps-c/step-03-issue-detection.md → references/issue-detection.md} +5 -5
  166. package/src/skf-refine-architecture/references/refinement-rules.md +2 -0
  167. package/src/skf-refine-architecture/{steps-c/step-06-report.md → references/report.md} +14 -5
  168. package/src/skf-rename-skill/SKILL.md +82 -12
  169. package/src/skf-rename-skill/customize.toml +52 -0
  170. package/src/skf-rename-skill/{steps-c/step-02-execute.md → references/execute.md} +94 -99
  171. package/src/skf-rename-skill/references/health-check.md +30 -0
  172. package/src/skf-rename-skill/references/rebuild-context.md +110 -0
  173. package/src/skf-rename-skill/{steps-c/step-03-report.md → references/report.md} +13 -5
  174. package/src/skf-rename-skill/{steps-c/step-01-select.md → references/select.md} +59 -20
  175. package/src/skf-setup/SKILL.md +35 -35
  176. package/src/skf-setup/customize.toml +33 -0
  177. package/src/skf-setup/{steps-c/step-03-auto-index.md → references/auto-index.md} +10 -18
  178. package/src/skf-setup/{steps-c/step-01b-ccc-index.md → references/ccc-index.md} +14 -22
  179. package/src/skf-setup/{steps-c/step-01-detect-and-tier.md → references/detect-and-tier.md} +23 -10
  180. package/src/skf-setup/{steps-c/step-05-health-check.md → references/health-check.md} +1 -1
  181. package/src/skf-setup/{steps-c/step-04-report.md → references/report.md} +21 -19
  182. package/src/skf-setup/references/tier-rules.md +1 -1
  183. package/src/skf-setup/{steps-c/step-02-write-config.md → references/write-config.md} +14 -13
  184. package/src/skf-test-skill/SKILL.md +77 -15
  185. package/src/skf-test-skill/customize.toml +54 -0
  186. package/src/skf-test-skill/{steps-c/step-04-coherence-check.md → references/coherence-check.md} +28 -71
  187. package/src/skf-test-skill/{steps-c/step-03-coverage-check.md → references/coverage-check.md} +16 -39
  188. package/src/skf-test-skill/{steps-c/step-02-detect-mode.md → references/detect-mode.md} +4 -26
  189. package/src/skf-test-skill/{steps-c/step-04b-external-validators.md → references/external-validators.md} +6 -28
  190. package/src/skf-test-skill/references/health-check.md +14 -0
  191. package/src/skf-test-skill/{steps-c/step-01-init.md → references/init.md} +21 -37
  192. package/src/skf-test-skill/references/migration-section-rules.md +4 -2
  193. package/src/skf-test-skill/{steps-c/step-06-report.md → references/report.md} +41 -51
  194. package/src/skf-test-skill/{steps-c/step-05-score.md → references/score.md} +26 -43
  195. package/src/skf-test-skill/references/scoring-rules.md +8 -6
  196. package/src/skf-test-skill/references/source-access-protocol.md +7 -5
  197. package/src/skf-test-skill/scripts/compute-score.py +88 -17
  198. package/src/skf-test-skill/templates/test-report-template.md +13 -13
  199. package/src/skf-update-skill/SKILL.md +23 -14
  200. package/src/skf-update-skill/customize.toml +44 -0
  201. package/src/skf-update-skill/{steps-c/step-02-detect-changes.md → references/detect-changes.md} +176 -68
  202. package/src/skf-update-skill/references/health-check.md +32 -0
  203. package/src/skf-update-skill/{steps-c/step-01-init.md → references/init.md} +56 -8
  204. package/src/skf-update-skill/references/manual-section-rules.md +4 -0
  205. package/src/skf-update-skill/references/merge-conflict-rules.md +4 -0
  206. package/src/skf-update-skill/{steps-c/step-04-merge.md → references/merge.md} +8 -8
  207. package/src/skf-update-skill/{steps-c/step-03-re-extract.md → references/re-extract.md} +53 -44
  208. package/src/skf-update-skill/references/remote-source-resolution.md +5 -1
  209. package/src/skf-update-skill/references/report.md +214 -0
  210. package/src/skf-update-skill/{steps-c/step-05-validate.md → references/validate.md} +5 -5
  211. package/src/skf-update-skill/{steps-c/step-06-write.md → references/write.md} +73 -51
  212. package/src/skf-verify-stack/SKILL.md +89 -17
  213. package/src/skf-verify-stack/assets/feasibility-report-template.md +4 -4
  214. package/src/skf-verify-stack/customize.toml +50 -0
  215. package/src/skf-verify-stack/references/coverage-patterns.md +2 -2
  216. package/src/skf-verify-stack/{steps-c/step-02-coverage.md → references/coverage.md} +7 -7
  217. package/src/skf-verify-stack/{steps-c/step-07-health-check.md → references/health-check.md} +7 -5
  218. package/src/skf-verify-stack/references/init.md +166 -0
  219. package/src/skf-verify-stack/references/integration-verification-rules.md +1 -1
  220. package/src/skf-verify-stack/{steps-c/step-03-integrations.md → references/integrations.md} +12 -12
  221. package/src/skf-verify-stack/{steps-c/step-06-report.md → references/report.md} +22 -41
  222. package/src/skf-verify-stack/{steps-c/step-04-requirements.md → references/requirements.md} +7 -7
  223. package/src/skf-verify-stack/{steps-c/step-05-synthesize.md → references/synthesize.md} +8 -8
  224. package/tools/validate-docs-drift.js +1 -1
  225. package/src/skf-audit-skill/steps-c/step-01-init.md +0 -221
  226. package/src/skf-refine-architecture/steps-c/step-01-init.md +0 -136
  227. package/src/skf-rename-skill/steps-c/step-04-health-check.md +0 -22
  228. package/src/skf-test-skill/steps-c/step-07-health-check.md +0 -25
  229. package/src/skf-update-skill/steps-c/step-07-report.md +0 -148
  230. package/src/skf-update-skill/steps-c/step-08-health-check.md +0 -22
  231. package/src/skf-verify-stack/steps-c/step-01-init.md +0 -178
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: skf-create-stack-skill
3
- description: Consolidated project stack skill with integration patterns — code-mode (analyzes manifests) or compose-mode (synthesizes from existing skills + architecture doc). Use when the user requests to "create a stack skill."
3
+ description: Consolidated project stack skill with integration patterns — code-mode (analyzes manifests) or compose-mode (synthesizes from existing skills + architecture doc). Use when the user requests to "create a stack skill", "forge a stack", or "stack this project".
4
4
  ---
5
5
 
6
6
  # Create Stack Skill
@@ -9,46 +9,80 @@ description: Consolidated project stack skill with integration patterns — code
9
9
 
10
10
  Produces a consolidated stack skill documenting how libraries connect. **Code-mode** analyzes dependency manifests and co-import patterns from actual source code. **Compose-mode** synthesizes from pre-generated individual skills and architecture documents when no codebase exists yet. Every finding must trace to actual code with file:line citations; in compose-mode, inferred integrations are permitted but must be labeled `[inferred from shared domain]`.
11
11
 
12
+ ## Conventions
13
+
14
+ - Bare paths (e.g. `references/<name>.md`) resolve from the skill root.
15
+ - `references/` holds prompt content carved out of SKILL.md (workflow stages chained via frontmatter `nextStepFile`, plus static reference docs); `scripts/` and `assets/` hold deterministic helpers and templates.
16
+ - `{skill-root}` resolves to this skill's installed directory (where `customize.toml` lives, if present).
17
+ - `{project-root}`-prefixed paths resolve from the project working directory.
18
+ - `{skill-name}` resolves to the skill directory's basename.
19
+
12
20
  ## Role
13
21
 
14
- You are a dependency analyst and integration architect operating in Ferris Architect mode. You bring expertise in dependency analysis, cross-library integration patterns, and compositional architecture, while the user brings their project knowledge and scope preferences.
22
+ You are a dependency analyst and integration architect. You bring expertise in dependency analysis, cross-library integration patterns, and compositional architecture, while the user brings their project knowledge and scope preferences.
15
23
 
16
24
  ## Workflow Rules
17
25
 
18
26
  These rules apply to every step in this workflow:
19
27
 
20
28
  - Zero hallucination — all extracted content must trace to actual source code (compose-mode inferences must be labeled)
21
- - Read each step file completely before taking any action
22
- - Follow the mandatory sequence in each step exactly — do not skip, reorder, or optimize
23
29
  - Only load one step file at a time — never preload future steps
24
30
  - If any instruction references a subprocess or tool you lack, achieve the outcome in your main context thread
25
31
  - Always communicate in `{communication_language}`
26
32
  - If `{headless_mode}` is true, auto-proceed through confirmation gates with their default action and log each auto-decision
27
- - **Workflow state contract `workflow_warnings[]` accumulator (M4):** every step that emits a warning ("log a warning", "record in workflow state for the evidence report", "Warning: ...", etc.) MUST append a structured entry to a single in-memory list named `workflow_warnings[]`. Each entry has the shape `{step: "step-NN", severity: "info|warn|error", code: "<short-slug>", message: "<human text>", context: {<optional fields>}}`. Step-07 surfaces these in `evidence-report.md`; step-08 may add validation findings; step-09 §5 reads the accumulated list and renders the user-facing "Warnings" section. Do not invent a per-step warning channel — there is exactly one accumulator for the whole workflow.
33
+ - Warnings use a single accumulator see `## Workflow state contract` below for shape and surfacing.
34
+
35
+ ## Workflow state contract
36
+
37
+ Every step that emits a warning ("log a warning", "record in workflow state for the evidence report", "Warning: ...", etc.) appends a structured entry to a single in-memory list named `workflow_warnings[]`. Each entry has the shape `{step: "step-NN", severity: "info|warn|error", code: "<short-slug>", message: "<human text>", context: {<optional fields>}}`. Step 7 surfaces these in `evidence-report.md`; step 8 may add validation findings; step 9 §5 reads the accumulated list and renders the user-facing "Warnings" section. There is exactly one accumulator for the whole workflow — do not invent per-step channels.
28
38
 
29
39
  ## Stages
30
40
 
31
41
  | # | Step | File | Auto-proceed |
32
42
  |---|------|------|--------------|
33
- | 1 | Initialize & Mode Detection | steps-c/step-01-init.md | No (confirm) |
34
- | 2 | Detect Manifests | steps-c/step-02-detect-manifests.md | Yes |
35
- | 3 | Rank & Confirm Libraries | steps-c/step-03-rank-and-confirm.md | No (confirm) |
36
- | 4 | Parallel Extract | steps-c/step-04-parallel-extract.md | Yes |
37
- | 5 | Detect Integrations | steps-c/step-05-detect-integrations.md | Yes |
38
- | 6 | Compile Stack | steps-c/step-06-compile-stack.md | No (review) |
39
- | 7 | Generate Output | steps-c/step-07-generate-output.md | Yes |
40
- | 8 | Validate | steps-c/step-08-validate.md | Yes |
41
- | 9 | Report | steps-c/step-09-report.md | Yes |
42
- | 10 | Workflow Health Check | steps-c/step-10-health-check.md | Yes |
43
+ | 1 | Initialize & Mode Detection | references/init.md | No (confirm) |
44
+ | 2 | Detect Manifests | references/detect-manifests.md | Yes |
45
+ | 3 | Rank & Confirm Libraries | references/rank-and-confirm.md | No (confirm) |
46
+ | 4 | Parallel Extract | references/parallel-extract.md | Yes |
47
+ | 5 | Detect Integrations | references/detect-integrations.md | Yes |
48
+ | 6 | Compile Stack | references/compile-stack.md | No (review) |
49
+ | 7 | Generate Output | references/generate-output.md | Yes |
50
+ | 8 | Validate | references/validate.md | Yes |
51
+ | 9 | Report | references/report.md | Yes |
52
+ | 10 | Workflow Health Check | references/health-check.md | Yes |
43
53
 
44
54
  ## Invocation Contract
45
55
 
46
56
  | Aspect | Detail |
47
57
  |--------|--------|
48
58
  | **Inputs** | project_path [required], mode (code/compose) [auto-detected] |
49
- | **Gates** | step-03: Confirm Gate [C] | step-06: Review Gate [C] |
59
+ | **Gates** | step 3: Confirm Gate [C] | step 6: Review Gate [C] |
50
60
  | **Outputs** | SKILL.md (stack), context-snippet.md, metadata.json |
51
61
  | **Headless** | All gates auto-resolve with default action when `{headless_mode}` is true |
62
+ | **Exit codes** | See "Exit Codes" below |
63
+
64
+ ## Exit Codes
65
+
66
+ Every HARD HALT in this workflow exits with a stable code so headless automators can branch on the failure class without grepping message text:
67
+
68
+ | Code | Meaning | Raised by |
69
+ | ---- | -------------------- | ------------------------------------------------------------------------------------------ |
70
+ | 0 | success | step 10 (terminal handoff to shared health-check) |
71
+ | 2 | input-missing / input-invalid | step 1 §0 (`config.yaml` missing or malformed); step 2 §2 headless cannot proceed without manifests (S2); step 4 §3 all extractions failed (B7); step 5 §2 feasibility-report `schemaVersion` mismatch; compose-mode-rules `schemaVersion` mismatch |
72
+ | 3 | resolution-failure | step 1 §1 (`forge-tier.yaml` missing); step 2 §0 compose-mode skill resolution corruption (manifest + symlink both fail); step 2 §0 compose-mode zero qualifying skills (S1/S3) |
73
+ | 4 | write-failure | step 7 §1 stage-dir / commit-dir failure; step 7 §1 group-dir collision when an existing non-stack skill occupies the target path |
74
+ | 5 | overwrite-cancelled | step 7 collision when the user declines to replace an existing stack package |
75
+ | 6 | user-cancelled | any interactive menu in step 3 / step 6 (user selected `[X]` Cancel and exit) |
76
+
77
+ ## Result Contract (Headless)
78
+
79
+ When `{headless_mode}` is true, step 9 emits a single-line JSON envelope on **stdout** before chaining to step 10, and every HARD HALT emits the same envelope shape on **stderr** with `status: "error"`:
80
+
81
+ ```
82
+ SKF_STACK_RESULT_JSON: {"status":"success|error","skill_package":"…|null","skill_name":"…","stack_libraries":["…"],"mode":"code|compose","exit_code":0,"halt_reason":null}
83
+ ```
84
+
85
+ `status` is `"success"` on the terminal happy path, `"error"` on any HALT. `skill_package` is the absolute path to the committed stack-skill directory (or `null` on error before commit). `skill_name` is the stack skill's published name (e.g. `{project_name}-stack`). `stack_libraries` is the array of library names included in the stack (constituent skill names in compose-mode, dependency names in code-mode). `mode` is `"code"` or `"compose"` per the run's resolved mode. `halt_reason` is one of: `null` (success), `"input-missing"`, `"input-invalid"`, `"forge-tier-missing"`, `"config-missing"`, `"no-manifests"`, `"all-extractions-failed"`, `"schema-version-mismatch"`, `"resolution-failure"`, `"write-failure"`, `"overwrite-cancelled"`, `"user-cancelled"`. `exit_code` matches the table above.
52
86
 
53
87
  ## On Activation
54
88
 
@@ -61,4 +95,29 @@ These rules apply to every step in this workflow:
61
95
  3. **Preferences fallback.** Otherwise, read `headless_mode` from `{sidecar_path}/preferences.yaml` (`true` or `false`).
62
96
  4. **Default:** `false`.
63
97
 
64
- 3. Load, read the full file, and then execute `./steps-c/step-01-init.md` to begin the workflow.
98
+ 3. **Resolve workflow customization.** Run:
99
+
100
+ ```bash
101
+ python3 {project-root}/_bmad/scripts/resolve_customization.py \
102
+ --skill {skill-root} --key workflow
103
+ ```
104
+
105
+ The script merges the three customization layers per `bmad-customize`'s structural merge rules (scalars override, arrays append):
106
+
107
+ - `{skill-root}/customize.toml` — bundled defaults
108
+ - `_bmad/custom/<skill-name>.toml` under `{project-root}` — team overrides (committed)
109
+ - `_bmad/custom/<skill-name>.user.toml` under `{project-root}` — personal overrides (gitignored)
110
+
111
+ If the script fails or is missing, fall back to reading `{skill-root}/customize.toml` directly — the bundled defaults are an empty string for each path scalar.
112
+
113
+ Apply the path-scalar fallback now so stage files don't have to repeat the conditional logic. For each of the five scalars, if the merged value is empty or absent, use the bundled default:
114
+
115
+ - `{stackSkillTemplatePath}` ← `workflow.stack_skill_template_path` if non-empty, else `assets/stack-skill-template.md`
116
+ - `{integrationPatternsPath}` ← `workflow.integration_patterns_path` if non-empty, else `references/integration-patterns.md`
117
+ - `{manifestPatternsPath}` ← `workflow.manifest_patterns_path` if non-empty, else `references/manifest-patterns.md`
118
+ - `{composeModeRulesPath}` ← `workflow.compose_mode_rules_path` if non-empty, else `references/compose-mode-rules.md`
119
+ - `{provenanceMapSchemaPath}` ← `workflow.provenance_map_schema_path` if non-empty, else `assets/provenance-map-schema.md`
120
+
121
+ Stash all five as workflow-context variables. Stage files reference `{stackSkillTemplatePath}` / `{integrationPatternsPath}` / `{manifestPatternsPath}` / `{composeModeRulesPath}` / `{provenanceMapSchemaPath}` directly — no conditional at the usage site. Empty-string overrides cleanly fall through to the bundled default; non-empty values let orgs swap in house-style copies without forking the skill.
122
+
123
+ 4. Load, read the full file, and then execute `references/init.md` to begin the workflow.
@@ -0,0 +1,102 @@
1
+ ---
2
+ type: static-reference
3
+ ---
4
+
5
+ # provenance-map.json Schema
6
+
7
+ Canonical schema templates for the workspace `provenance-map.json` artifact written in step 7 §7. Two variants exist — choose by the run's resolved mode:
8
+
9
+ - **code-mode** — when the workflow analyzed a real codebase with manifest files and AST-extracted exports
10
+ - **compose-mode** — when the workflow synthesized a stack from pre-generated constituent skills + an architecture document
11
+
12
+ Both variants share the top-level `provenance_version`, `skill_name`, `skill_type`, `generated_at`, `entries[]`, and `integrations[]` shape. They differ in source-anchor fields (`source_repo` / `source_commit` / `source_ref`), in `entries[].extraction_method` values, in `integrations[].detection_method` values, and in compose-mode's additional `constituents[]` array which enables drift detection via metadata-hash comparison.
13
+
14
+ > **Note:** Per-export entries use the same schema as single skills (see `skill-sections.md`), with `source_library` identifying the originating library. In compose-mode, `constituents[]` enables audit to detect constituent drift via metadata hash comparison.
15
+
16
+ ## Code-mode variant
17
+
18
+ Used when the workflow ran in code-mode against an actual codebase. `source_repo` and `source_commit` capture the upstream anchor(s); `entries[].extraction_method` records how each export was discovered (`ast_bridge`, `source_reading`, or `qmd_bridge`). `integrations[].detection_method` is `"co-import grep"` because integration pairs are confirmed by co-import file evidence.
19
+
20
+ ```json
21
+ {
22
+ "provenance_version": "2.0",
23
+ "skill_name": "{project_name}-stack",
24
+ "skill_type": "stack",
25
+ "source_repo": ["{repo_url_1}", "{repo_url_2}"],
26
+ "source_commit": {"{repo_1}": "{hash_1}", "{repo_2}": "{hash_2}"},
27
+ "generated_at": "{ISO-8601}",
28
+ "entries": [
29
+ {
30
+ "export_name": "{name}",
31
+ "export_type": "{type}",
32
+ "source_library": "{library-name}",
33
+ "params": [],
34
+ "return_type": "{type}",
35
+ "source_file": "{file}",
36
+ "source_line": 0,
37
+ "confidence": "T1|T1-low|T2",
38
+ "extraction_method": "ast_bridge|source_reading|qmd_bridge",
39
+ "signature_source": "T1|T2|T3"
40
+ }
41
+ ],
42
+ "integrations": [
43
+ {
44
+ "libraries": ["{libA}", "{libB}"],
45
+ "pattern_type": "{type}",
46
+ "detection_method": "co-import grep",
47
+ "co_import_files": [{"file": "{path}", "line": 0}],
48
+ "confidence": "T1|T2"
49
+ }
50
+ ]
51
+ }
52
+ ```
53
+
54
+ ## Compose-mode variant
55
+
56
+ Used when the workflow ran in compose-mode against pre-generated constituent skills. Source-anchor fields (`source_repo`, `source_commit`, `source_ref`) are `null` because there is no codebase to anchor against — provenance traces back to the constituent skills instead, captured in the `constituents[]` array. Each entry's `extraction_method` is `"compose-from-skill"`; integrations have `detection_method` of `"architecture_co_mention"` (named in the architecture doc) or `"inferred_from_shared_domain"` (synthesized inference, must carry T2/T3 confidence).
57
+
58
+ ```json
59
+ {
60
+ "provenance_version": "2.0",
61
+ "skill_name": "{project_name}-stack",
62
+ "skill_type": "stack",
63
+ "source_repo": null,
64
+ "source_commit": null,
65
+ "source_ref": null,
66
+ "generated_at": "{ISO-8601}",
67
+ "entries": [
68
+ {
69
+ "export_name": "{name}",
70
+ "export_type": "{type}",
71
+ "source_library": "{library-name}",
72
+ "params": [],
73
+ "return_type": "{type}",
74
+ "source_file": "{from constituent skill}",
75
+ "source_line": 0,
76
+ "confidence": "T1|T1-low|T2",
77
+ "extraction_method": "compose-from-skill",
78
+ "signature_source": "T1|T2|T3"
79
+ }
80
+ ],
81
+ "integrations": [
82
+ {
83
+ "libraries": ["{libA}", "{libB}"],
84
+ "pattern_type": "{type}",
85
+ "detection_method": "architecture_co_mention|inferred_from_shared_domain",
86
+ "co_import_files": [],
87
+ "confidence": "T2|T3"
88
+ }
89
+ ],
90
+ "constituents": [
91
+ {
92
+ "skill_name": "{constituent-skill-name}",
93
+ "skill_path": "skills/{skill-dir}/",
94
+ "version": "{version from constituent metadata.json}",
95
+ "composed_at": "{ISO-8601}",
96
+ "metadata_hash": "sha256:{hash of constituent metadata.json}"
97
+ }
98
+ ]
99
+ }
100
+ ```
101
+
102
+ **Use the `metadata_hash` value already stored in workflow state during step 2 (S13) — do NOT re-read and re-hash at step 7 time. The stored hash captures the state as it was at manifest-detection time, which is the correct provenance anchor.**
@@ -32,7 +32,7 @@ description: >
32
32
 
33
33
  | Library | Imports | Key Exports | Confidence | Reference |
34
34
  |---------|---------|-------------|------------|-----------|
35
- | {name} | {count} | {top_exports} | {tier} | [ref](./references/{name}.md) |
35
+ | {name} | {count} | {top_exports} | {tier} | [ref](references/{name}.md) |
36
36
 
37
37
  ## Per-Library Summaries
38
38
 
@@ -0,0 +1,46 @@
1
+ # DO NOT EDIT -- overwritten on every update.
2
+ #
3
+ # Workflow customization surface for skf-create-stack-skill.
4
+
5
+ [workflow]
6
+
7
+ # --- Configurable below. Overrides merge per BMad structural rules: ---
8
+ # scalars: override wins • arrays (persistent_facts, activation_steps_*): append
9
+ # arrays-of-tables with `code`/`id`: replace matching items, append new ones.
10
+
11
+ # Steps to run before the standard activation (uv probe, config load).
12
+ # Overrides append. Use for org-wide pre-flight checks (auth, network,
13
+ # compliance) that must precede any stack compilation work.
14
+
15
+ activation_steps_prepend = []
16
+
17
+ # Steps to run after activation but before the first stage executes.
18
+ # Overrides append. Use for context loads or banner customization that
19
+ # should run once activation completes successfully.
20
+
21
+ activation_steps_append = []
22
+
23
+ # Persistent facts the workflow keeps in mind for the whole run
24
+ # (house style, naming conventions, integration-pattern guardrails).
25
+ # Overrides append.
26
+ #
27
+ # Each entry is either:
28
+ # - a literal sentence, e.g. "Stack skills must cite their constituent libraries."
29
+ # - a file reference prefixed with `file:`, e.g.
30
+ # "file:{project-root}/docs/stack-style.md" (globs supported; file
31
+ # contents are loaded and treated as facts).
32
+
33
+ persistent_facts = [
34
+ "file:{project-root}/**/project-context.md",
35
+ ]
36
+
37
+ # --- Optional asset overrides ---
38
+ #
39
+ # Lift the canonical asset paths so orgs can substitute house-style copies
40
+ # without forking the skill. Empty string = use the bundled default.
41
+
42
+ stack_skill_template_path = ""
43
+ integration_patterns_path = ""
44
+ manifest_patterns_path = ""
45
+ compose_mode_rules_path = ""
46
+ provenance_map_schema_path = ""
@@ -1,8 +1,10 @@
1
1
  ---
2
- nextStepFile: './step-07-generate-output.md'
2
+ nextStepFile: 'generate-output.md'
3
3
  stackSkillTemplate: 'assets/stack-skill-template.md'
4
4
  ---
5
5
 
6
+ <!-- Config: communicate in {communication_language}. Artifact text in {document_output_language}. -->
7
+
6
8
  # Step 6: Compile Stack Skill
7
9
 
8
10
  ## STEP GOAL:
@@ -17,8 +19,6 @@ Assemble the main SKILL.md by combining per-library extractions with the integra
17
19
 
18
20
  ## MANDATORY SEQUENCE
19
21
 
20
- **CRITICAL:** Follow this sequence exactly. Do not skip, reorder, or improvise.
21
-
22
22
  ### 1. Load Template Structure
23
23
 
24
24
  Load `{stackSkillTemplate}` and prepare SKILL.md section structure.
@@ -74,7 +74,7 @@ For each confirmed library (ordered by integration connectivity, then import cou
74
74
  - Key exports used in this project
75
75
  - Usage patterns from extraction
76
76
  - Confidence tier label
77
- - Link to reference file: `./references/{library}.md`
77
+ - Link to reference file: `references/{library}.md`
78
78
 
79
79
  ### 5. Compile Project Conventions
80
80
 
@@ -117,7 +117,7 @@ Create the reference index table:
117
117
 
118
118
  ### 8. Present MENU OPTIONS
119
119
 
120
- Display: **Select:** [C] Continue to Output Generation
120
+ Display: **Select:** [C] Continue to Output Generation | [X] Cancel and exit
121
121
 
122
122
  #### EXECUTION RULES:
123
123
 
@@ -128,5 +128,6 @@ Display: **Select:** [C] Continue to Output Generation
128
128
  #### Menu Handling Logic:
129
129
 
130
130
  - IF C: Store skill_content, then load, read entire file, then execute {nextStepFile}
131
+ - 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
131
132
  - IF Any other: Process as feedback, adjust compilation, redisplay preview, then [Redisplay Menu Options](#8-present-menu-options)
132
133
 
@@ -1,3 +1,5 @@
1
+ <!-- Config: communicate in {communication_language}. -->
2
+
1
3
  # Compose Mode Rules
2
4
 
3
5
  Rules for synthesizing a stack skill from pre-generated individual skills and an architecture document, without requiring a codebase.
@@ -19,7 +21,7 @@ Skills use version-nested directories — see `knowledge/version-paths.md` for t
19
21
 
20
22
  ## Compose-mode Co-mention Precision
21
23
 
22
- Prose co-mention detection is heuristic — it can only provide `Plausible`-class evidence (compared to code-mode's co-imports, which are literal). To reduce false positives the matcher in step-05 §2 applies three guards:
24
+ Prose co-mention detection is heuristic — it can only provide `Plausible`-class evidence (compared to code-mode's co-imports, which are literal). To reduce false positives the matcher in step 5 §2 applies three guards:
23
25
 
24
26
  1. **Word-boundary matching** (`\b{skill_name}\b`, case-insensitive). Substring matches are rejected (no `react` inside `reactive`).
25
27
  2. **Section filtering.** Paragraphs under H1/H2 headers that normalise to `introduction`, `overview`, `glossary`, `table of contents`, `references`, `appendix`, or `index` are excluded — they typically enumerate all libraries without describing integration. Headings themselves are also excluded as co-mention sources.
@@ -1,9 +1,12 @@
1
1
  ---
2
- nextStepFile: './step-06-compile-stack.md'
2
+ nextStepFile: 'compile-stack.md'
3
3
  integrationPatterns: 'references/integration-patterns.md'
4
4
  composeModeRules: 'references/compose-mode-rules.md'
5
+ pairIntersectScript: '{project-root}/src/shared/scripts/skf-pair-intersect.py'
5
6
  ---
6
7
 
8
+ <!-- Config: communicate in {communication_language}. -->
9
+
7
10
  # Step 5: Detect Integrations
8
11
 
9
12
  ## STEP GOAL:
@@ -18,17 +21,35 @@ Analyze co-import patterns between confirmed libraries to identify integration p
18
21
 
19
22
  ## MANDATORY SEQUENCE
20
23
 
21
- **CRITICAL:** Follow this sequence exactly. Do not skip, reorder, or improvise.
22
-
23
24
  ### 1. Generate Library Pairs
24
25
 
25
- From `confirmed_dependencies`, generate all unique pairs:
26
- - N libraries → N*(N-1)/2 pairs
27
- - Skip pairs where either library had extraction failure in step 04
28
-
29
- **File-list intersection fast path (MANDATORY first pass, all N):** before issuing any pair grep, compute each pair's candidate file set by **intersecting the per-library file lists recorded by step-03 import-count extraction**. Pairs with an empty intersection cannot be integration candidates by construction — drop them. Subsequent grep passes run only against pairs with a non-empty intersection, and grep scope is restricted to those intersection files rather than the whole source tree. This is NOT a "subprocess-unavailable" fallback; it is the default strategy for every N. Rationale: at N≈21 this collapses 210 prescribed pair greps to ~12 non-empty-intersection pairs in typical codebases; at larger N the compression is even greater.
30
-
31
- **Top-K cap (S7, lowered to 20):** If the file-list-intersection prune still leaves more than **20** non-empty-intersection pairs, cap at the top 20 pairs ranked by intersection size (or by import count if tied). Dropped pairs are excluded from integration detection — warn the user explicitly: `"non-empty-intersection pair count {N} exceeds cap — analyzing top 20 by intersection size; {excluded_count} pairs skipped"`. Record this cap in the evidence report. The legacy 50-dependency threshold that formerly gated a separate Top-K pass is retired — the file-intersection prune does the bulk of the work and the cap is now a second-order safety limit, not a primary strategy.
26
+ From `confirmed_dependencies`, conceptually you have N*(N-1)/2 unordered pairs. Rather than enumerating and grep-testing each one, prune the matrix via a deterministic **file-list intersection fast path** (MANDATORY first pass, all N): pairs whose per-library file lists do not overlap cannot be integration candidates by construction — drop them. Subsequent grep passes (§2) run only against pairs with a non-empty intersection, and grep scope is restricted to those intersection files rather than the whole source tree. This is NOT a "subprocess-unavailable" fallback; it is the default strategy for every N. Rationale: at N≈21 this collapses 210 prescribed pair greps to ~12 non-empty-intersection pairs in typical codebases; at larger N the compression is even greater.
27
+
28
+ **Compute the intersection deterministically via the shared script:**
29
+
30
+ 1. **Build the libraries JSON** from the per-library file enumeration recorded by step 3 import-count extraction. Skip libraries where step 04 reported extraction failure. Shape:
31
+ ```json
32
+ [
33
+ {"name": "<library-name>", "files": ["<rel-path-forward-slash>", ...]},
34
+ ...
35
+ ]
36
+ ```
37
+ 2. **Invoke the script** via stdin (or a temp file under `{forge_data_folder}/` if stdin piping is unavailable):
38
+ ```bash
39
+ uv run {pairIntersectScript} intersect --libraries -
40
+ ```
41
+ piping the libraries JSON on stdin. The script emits:
42
+ ```json
43
+ {
44
+ "pairs": [{"a": "<lib>", "b": "<lib>", "intersection_count": N, "files": [...]}, ...],
45
+ "truncated": <bool>,
46
+ "total_pairs": <int>
47
+ }
48
+ ```
49
+ `pairs[]` is sorted by `intersection_count` DESC, then `(a, b)` ASC for stable ordering. Default Top-K cap is **20** (matches S7 below); pass `--top-k N` to override.
50
+ 3. **Parse the JSON result** and use `pairs[]` as the qualifying-pair set for §2 onward. The `intersection_count` is the candidate file count for the §2 2-file threshold pre-grep; `files[]` is the grep-scope for that pair.
51
+
52
+ **Top-K cap (S7, 20):** If the script's response has `truncated: true`, more pairs than the cap had non-empty intersections. Surface a user-visible warning composed as: `"non-empty-intersection pair count {total_pairs} exceeds cap — analyzing top 20 by intersection size; {total_pairs - 20} pairs skipped"`. Record this cap in the evidence report. (Tie-break by intersection size is what the script sorts on; if you need to override the cap intentionally, pass `--top-k N` and document the rationale.) The legacy 50-dependency threshold that formerly gated a separate Top-K pass is retired — the file-intersection prune does the bulk of the work and the cap is now a second-order safety limit, not a primary strategy.
32
53
 
33
54
  Report: "**Analyzing {pair_count} library pairs for integration patterns** (pruned from {N*(N-1)/2} via file-list intersection; {capped_count} after Top-K if applicable)**...**"
34
55
 
@@ -63,7 +84,7 @@ All integration evidence inherits confidence tiers from the source skills. Load
63
84
  - For each architecture-detected pair, include `VS overall: {overallVerdict}` and `VS pair: {verdict}` in the integration evidence per the format in `{composeModeRules}`. VS verdicts do not apply to inferred integrations since the VS report operates on architecture-described interactions only. Additionally, flag any pairs where VS reported `Risky` or `Blocked` by appending a `[VS: Risky]` or `[VS: Blocked]` warning annotation to the integration entry.
64
85
 
65
86
  If no architecture document available:
66
- - Infer potential integrations from skills sharing the same `language` field or sharing domain keywords in their SKILL.md descriptions (use the `usage_patterns` and `exports` fields from `per_library_extractions[]` built in step-04, or reload SKILL.md from the version-aware path: use `skill_package_path` from step-02, or resolve via `{skills_output_folder}/{skill_dir}/active/{skill_dir}/SKILL.md` — see `knowledge/version-paths.md`)
87
+ - Infer potential integrations from skills sharing the same `language` field or sharing domain keywords in their SKILL.md descriptions (use the `usage_patterns` and `exports` fields from `per_library_extractions[]` built in step 4, or reload SKILL.md from the version-aware path: use `skill_package_path` from step 2, or resolve via `{skills_output_folder}/{skill_dir}/active/{skill_dir}/SKILL.md` — see `knowledge/version-paths.md`)
67
88
  - Mark inferred integrations: `[inferred from shared domain]` — use this suffix instead of `[composed]` for inferred integrations
68
89
  - Inferred integrations qualify automatically — no file-count threshold applies
69
90
 
@@ -1,8 +1,11 @@
1
1
  ---
2
- nextStepFile: './step-03-rank-and-confirm.md'
2
+ nextStepFile: 'rank-and-confirm.md'
3
3
  manifestPatterns: 'references/manifest-patterns.md'
4
+ scanManifestsScript: '{project-root}/src/shared/scripts/skf-scan-manifests.py'
4
5
  ---
5
6
 
7
+ <!-- Config: communicate in {communication_language}. -->
8
+
6
9
  # Step 2: Detect Manifests
7
10
 
8
11
  ## STEP GOAL:
@@ -17,8 +20,6 @@ Scan the project root for dependency manifest files, parse each to extract depen
17
20
 
18
21
  ## MANDATORY SEQUENCE
19
22
 
20
- **CRITICAL:** Follow this sequence exactly. Do not skip, reorder, or improvise.
21
-
22
23
  ### 0. Check Compose Mode
23
24
 
24
25
  **If `compose_mode` is true AND `explicit_deps` was provided in step 01:**
@@ -57,7 +58,7 @@ For each skill found:
57
58
  2. Extract: name, language, confidence_tier, source_repo, exports count, version
58
59
  3. Store the skill group directory name as `skill_dir` (the top-level name under `{skills_output_folder}`, distinct from `name` — the directory may differ from the metadata name)
59
60
  4. Store the resolved package path as `skill_package_path` for use in later steps
60
- 5. **Hash the constituent metadata at read-time (S13):** compute `sha256` of the raw `metadata.json` bytes just read, and store it in workflow state as `metadata_hash` alongside `skill_package_path`. Step-07 uses this stored hash (not a re-read) for `constituents[].metadata_hash` in `provenance-map.json`, so drift between step-02 read and step-07 write is captured.
61
+ 5. **Hash the constituent metadata at read-time (S13):** compute `sha256` of the raw `metadata.json` bytes just read, and store it in workflow state as `metadata_hash` alongside `skill_package_path`. Step-07 uses this stored hash (not a re-read) for `constituents[].metadata_hash` in `provenance-map.json`, so drift between step 2 read and step 7 write is captured.
61
62
  6. Store as `raw_dependencies` with source: "existing_skill"
62
63
 
63
64
  Display:
@@ -85,20 +86,33 @@ Store the explicit list as `raw_dependencies` and skip to [Display Detection Sum
85
86
 
86
87
  **If no explicit list:** Continue to section 2.
87
88
 
88
- ### 2. Scan for Manifest Files
89
+ ### 2. Scan and Parse Manifests
90
+
91
+ Invoke the deterministic manifest scanner — it walks the project root, parses every recognised manifest, dedupes the production dep set, and flags monorepo layout:
92
+
93
+ ```bash
94
+ uv run {scanManifestsScript} scan {scan_root}
95
+ ```
89
96
 
90
- Load `{manifestPatterns}` for supported ecosystem detection patterns.
97
+ Where `{scan_root}` is the project root path. Load `{manifestPatterns}` for the ecosystem reference table that documents supported filenames, dependency keys, and normalisation rules; the script implements exactly that table (npm/pnpm/yarn, python pip/poetry/pdm, rust cargo, go modules, java/kotlin maven + gradle, ruby bundler, composer, swift package manager). Exclusion patterns (`node_modules/`, `.venv/`, `vendor/`, `dist/`, `build/`, `target/`, `.git/`, hidden dirs) are applied internally.
91
98
 
92
- Scan the project root (depth 0-1) for manifest files, **excluding directories listed in the Scan Exclusion Patterns section of `{manifestPatterns}`**:
99
+ Parse the JSON output shape:
93
100
 
94
- - Search for each supported manifest filename
95
- - Record: file path, ecosystem type, file size
96
- - **Apply exclusion patterns** from `{manifestPatterns}` — skip `node_modules/`, `.venv/`, `vendor/`, `dist/`, `build/`, `target/`, `.git/`, and all hidden directories when globbing
97
- - Note any unusual structures (monorepo with multiple manifests, workspace configurations)
101
+ ```
102
+ {
103
+ "manifests": [
104
+ {"path": "<rel-from-root>", "ecosystem": "<name>", "deps": [{"name": "...", "version": "..."}]},
105
+ ...
106
+ ],
107
+ "total_unique": N,
108
+ "monorepo": <bool>,
109
+ "warnings": ["..."] // optional, only if any parse warning fired
110
+ }
111
+ ```
98
112
 
99
- **If no manifest files found:**
113
+ If `manifests` is empty:
100
114
 
101
- **Headless auto-cancel (S2):** If `{headless_mode}` is true, do NOT wait for user input. Emit a structured error contract `{"status":"error","skill":"skf-create-stack-skill","stage":"step-02","reason":"no manifests found, headless cannot prompt"}` on stderr and exit non-zero. Headless mode cannot proceed without an explicit dependency list.
115
+ **Headless auto-cancel (S2):** If `{headless_mode}` is true, do NOT wait for user input. Emit a structured error contract `{"status":"error","skill":"skf-create-stack-skill","stage":"step 2","reason":"no manifests found, headless cannot prompt"}` on stderr and exit non-zero. Headless mode cannot proceed without an explicit dependency list.
102
116
 
103
117
  **Interactive mode:**
104
118
 
@@ -115,21 +129,7 @@ Searched for: package.json, requirements.txt, Cargo.toml, go.mod, pom.xml, build
115
129
 
116
130
  STOP — wait for user response.
117
131
 
118
- ### 3. Parse Each Manifest
119
-
120
- For each discovered manifest file:
121
-
122
- 1. Read the file contents
123
- 2. Extract dependency names and version constraints using ecosystem-specific parsing:
124
- - JSON manifests: parse dependencies/devDependencies keys
125
- - TOML manifests: parse [dependencies] sections
126
- - Text manifests: parse line-by-line (name==version or name>=version)
127
- - XML manifests: parse dependency elements
128
- - Gradle: parse implementation/api/compile declarations
129
- 3. Categorize: runtime vs dev-only
130
- 4. Normalize dependency names across ecosystems
131
-
132
- Deduplicate dependencies found across multiple manifests.
132
+ Otherwise, store the parsed `manifests[]` and `total_unique` as `raw_dependencies` (dedup is already applied by the scanner), surface any `warnings[]` to the user as parse-quality notes, and inspect the `monorepo` flag: if `true`, mention the monorepo layout in the detection summary so the user can decide whether to scope the ranking to a specific package or proceed across all manifests.
133
133
 
134
134
  ### 4. Display Detection Summary
135
135