bmad-module-skill-forge 2.2.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (435) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/README.md +49 -49
  3. package/docs/404.md +10 -8
  4. package/docs/_data/pinned.yaml +22 -13
  5. package/docs/_internal/STABILITY.md +58 -35
  6. package/docs/agents.md +39 -53
  7. package/docs/architecture.md +65 -51
  8. package/docs/bmad-synergy.md +53 -51
  9. package/docs/campaign.md +127 -75
  10. package/docs/concepts.md +34 -28
  11. package/docs/examples.md +70 -68
  12. package/docs/forge-auto.md +34 -31
  13. package/docs/getting-started.md +118 -57
  14. package/docs/how-it-works.md +25 -21
  15. package/docs/index.md +15 -15
  16. package/docs/skill-model.md +70 -59
  17. package/docs/troubleshooting.md +135 -18
  18. package/docs/verifying-a-skill.md +83 -57
  19. package/docs/why-skf.md +24 -22
  20. package/docs/workflows.md +274 -110
  21. package/package.json +18 -10
  22. package/src/forger/preferences.yaml +8 -1
  23. package/src/knowledge/agentskills-spec.md +2 -0
  24. package/src/knowledge/ccc-bridge.md +40 -24
  25. package/src/knowledge/confidence-tiers.md +9 -5
  26. package/src/knowledge/overview.md +3 -3
  27. package/src/knowledge/progressive-capability.md +8 -8
  28. package/src/knowledge/provenance-tracking.md +9 -5
  29. package/src/knowledge/qmd-registry.md +2 -2
  30. package/src/knowledge/skf-knowledge-index.csv +2 -2
  31. package/src/knowledge/skill-lifecycle.md +18 -11
  32. package/src/knowledge/split-body-strategy.md +0 -3
  33. package/src/knowledge/tool-resolution.md +4 -2
  34. package/src/knowledge/version-paths.md +101 -15
  35. package/src/module-help.csv +3 -3
  36. package/src/module.yaml +10 -0
  37. package/src/shared/data/ast-grep-recipes.yaml +608 -0
  38. package/src/shared/data/ide-context-files.json +30 -0
  39. package/src/shared/health-check.md +32 -12
  40. package/src/shared/references/description-guard-protocol.md +12 -9
  41. package/src/shared/references/feasibility-report-schema.md +19 -13
  42. package/src/shared/references/headless-gate-convention.md +55 -3
  43. package/src/shared/references/output-contract-schema.md +19 -8
  44. package/src/shared/references/pipeline-contracts.md +94 -29
  45. package/src/shared/references/tessl-review.md +77 -0
  46. package/src/shared/scripts/schemas/skf-analyze-result-envelope.v1.json +194 -0
  47. package/src/shared/scripts/schemas/skf-audit-result-envelope.v1.json +192 -0
  48. package/src/shared/scripts/schemas/skf-brief-result-envelope.v1.json +32 -4
  49. package/src/shared/scripts/schemas/skf-campaign-result-envelope.v1.json +174 -0
  50. package/src/shared/scripts/schemas/skf-create-skill-result-envelope.v1.json +284 -0
  51. package/src/shared/scripts/schemas/skf-drop-skill-result-envelope.v1.json +164 -0
  52. package/src/shared/scripts/schemas/skf-export-result-envelope.v1.json +160 -0
  53. package/src/shared/scripts/schemas/skf-quick-skill-result-envelope.v1.json +261 -0
  54. package/src/shared/scripts/schemas/skf-refine-architecture-result-envelope.v1.json +192 -0
  55. package/src/shared/scripts/schemas/skf-rename-skill-result-envelope.v1.json +179 -0
  56. package/src/shared/scripts/schemas/skf-setup-result-envelope.v1.json +27 -11
  57. package/src/shared/scripts/schemas/skf-stack-result-envelope.v1.json +176 -0
  58. package/src/shared/scripts/schemas/skf-test-result-envelope.v1.json +173 -0
  59. package/src/shared/scripts/schemas/skf-update-result-envelope.v1.json +19 -5
  60. package/src/shared/scripts/schemas/skf-verify-stack-result-envelope.v1.json +180 -0
  61. package/src/shared/scripts/schemas/skill-brief.v1.json +34 -0
  62. package/src/shared/scripts/schemas/workspace-detection.v1.json +1 -1
  63. package/src/shared/scripts/skf-atomic-write.py +30 -14
  64. package/src/shared/scripts/skf-build-change-manifest.py +2203 -24
  65. package/src/shared/scripts/skf-ccc-git-hygiene.py +532 -0
  66. package/src/shared/scripts/skf-check-unit-records.py +184 -0
  67. package/src/shared/scripts/skf-check-workspace-drift.py +538 -9
  68. package/src/shared/scripts/skf-classify-changed-files.py +694 -0
  69. package/src/shared/scripts/skf-comention-pairs.py +1333 -123
  70. package/src/shared/scripts/skf-compare-file-hashes.py +1 -1
  71. package/src/shared/scripts/skf-count-imports.py +1867 -0
  72. package/src/shared/scripts/skf-count-tokens.py +1 -1
  73. package/src/shared/scripts/skf-derive-assembly-shape.py +3 -2
  74. package/src/shared/scripts/skf-description-guard.py +99 -11
  75. package/src/shared/scripts/skf-detect-docs.py +694 -2
  76. package/src/shared/scripts/skf-detect-language.py +486 -107
  77. package/src/shared/scripts/skf-detect-registry.py +887 -0
  78. package/src/shared/scripts/skf-detect-scripts-assets.py +1 -1
  79. package/src/shared/scripts/skf-detect-tools.py +209 -27
  80. package/src/shared/scripts/skf-detect-workspaces.py +506 -30
  81. package/src/shared/scripts/skf-disqualify-candidates.py +821 -182
  82. package/src/shared/scripts/skf-emit-brief-result-envelope.py +69 -191
  83. package/src/shared/scripts/skf-emit-result-envelope.py +1604 -106
  84. package/src/shared/scripts/skf-enumerate-stack-skills.py +986 -117
  85. package/src/shared/scripts/skf-extract-public-api.py +4084 -85
  86. package/src/shared/scripts/skf-extraction-inventory.py +746 -0
  87. package/src/shared/scripts/skf-extraction-snapshot.py +539 -0
  88. package/src/shared/scripts/skf-fetch-temporal.py +674 -0
  89. package/src/shared/scripts/skf-find-cycles.py +97 -29
  90. package/src/shared/scripts/skf-find-test-report.py +476 -0
  91. package/src/shared/scripts/skf-forge-tier-rw.py +444 -203
  92. package/src/shared/scripts/skf-github-fetch.py +365 -0
  93. package/src/shared/scripts/skf-github-probe.py +661 -0
  94. package/src/shared/scripts/skf-hash-content.py +166 -12
  95. package/src/shared/scripts/skf-language-corpora.py +1 -1
  96. package/src/shared/scripts/skf-load-provenance.py +159 -27
  97. package/src/shared/scripts/skf-manifest-ops.py +1 -1
  98. package/src/shared/scripts/skf-merge-ccc-exclusions.py +2307 -223
  99. package/src/shared/scripts/skf-merge-doc-urls.py +1 -1
  100. package/src/shared/scripts/skf-names-present.py +221 -0
  101. package/src/shared/scripts/skf-pair-intersect.py +119 -28
  102. package/src/shared/scripts/skf-parse-gaps.py +1384 -0
  103. package/src/shared/scripts/skf-preapply.py +1 -1
  104. package/src/shared/scripts/skf-preflight.py +161 -27
  105. package/src/shared/scripts/skf-promote-staged.py +430 -0
  106. package/src/shared/scripts/skf-provenance-gap-dispatch.py +39 -7
  107. package/src/shared/scripts/skf-qmd-classify-collections.py +229 -45
  108. package/src/shared/scripts/skf-quick-batch.py +774 -0
  109. package/src/shared/scripts/skf-rebuild-managed-sections.py +972 -88
  110. package/src/shared/scripts/skf-recommend-scope-type.py +323 -156
  111. package/src/shared/scripts/skf-render-metadata-stats.py +156 -12
  112. package/src/shared/scripts/skf-render-quick-metadata.py +132 -28
  113. package/src/shared/scripts/skf-render-stack-metadata.py +976 -0
  114. package/src/shared/scripts/skf-resolve-authoritative-files.py +128 -13
  115. package/src/shared/scripts/skf-resolve-package.py +523 -106
  116. package/src/shared/scripts/skf-rewrite-skill-name.py +433 -47
  117. package/src/shared/scripts/skf-run-lock.py +577 -0
  118. package/src/shared/scripts/skf-scan-manifests.py +998 -57
  119. package/src/shared/scripts/skf-scan-skill-md-structure.py +1341 -37
  120. package/src/shared/scripts/skf-severity-classify.py +712 -108
  121. package/src/shared/scripts/skf-shape-detect.py +298 -204
  122. package/src/shared/scripts/skf-shard-body.py +9 -8
  123. package/src/shared/scripts/skf-skill-inventory.py +2412 -89
  124. package/src/shared/scripts/skf-skills-module.py +472 -0
  125. package/src/shared/scripts/skf-source-tree.py +1796 -0
  126. package/src/shared/scripts/skf-structural-diff.py +670 -119
  127. package/src/shared/scripts/skf-tessl-review.py +706 -0
  128. package/src/shared/scripts/skf-update-active-symlink.py +5 -5
  129. package/src/shared/scripts/skf-update-run-state.py +624 -0
  130. package/src/shared/scripts/skf-validate-brief-inputs.py +92 -29
  131. package/src/shared/scripts/skf-validate-brief-schema.py +4 -1
  132. package/src/shared/scripts/skf-validate-feasibility-report.py +577 -66
  133. package/src/shared/scripts/skf-validate-frontmatter.py +103 -26
  134. package/src/shared/scripts/skf-validate-output.py +712 -64
  135. package/src/shared/scripts/skf-validate-pins.py +1 -1
  136. package/src/shared/scripts/skf-verify-no-trace.py +116 -10
  137. package/src/shared/scripts/skf-verify-provenance-completeness.py +2919 -54
  138. package/src/shared/scripts/skf-write-skill-brief.py +367 -19
  139. package/src/shared/tool-requirements.yaml +201 -0
  140. package/src/skf-analyze-source/SKILL.md +41 -36
  141. package/src/skf-analyze-source/assets/skill-brief-schema.md +7 -8
  142. package/src/skf-analyze-source/customize.toml +36 -24
  143. package/src/skf-analyze-source/references/auto-docs-only.md +58 -20
  144. package/src/skf-analyze-source/references/continue.md +2 -13
  145. package/src/skf-analyze-source/references/discover-additional-source.md +147 -0
  146. package/src/skf-analyze-source/references/generate-briefs.md +121 -55
  147. package/src/skf-analyze-source/references/headless-contract.md +42 -15
  148. package/src/skf-analyze-source/references/identify-units.md +96 -110
  149. package/src/skf-analyze-source/references/init.md +73 -71
  150. package/src/skf-analyze-source/references/map-and-detect.md +123 -105
  151. package/src/skf-analyze-source/references/map-unit-exports.md +68 -0
  152. package/src/skf-analyze-source/references/recommend.md +51 -70
  153. package/src/skf-analyze-source/references/scan-project.md +60 -84
  154. package/src/skf-analyze-source/references/scan-root.md +39 -0
  155. package/src/skf-analyze-source/references/step-auto-scope-coexistence.md +47 -0
  156. package/src/skf-analyze-source/references/step-auto-scope-corpora.md +53 -0
  157. package/src/skf-analyze-source/references/step-auto-scope-split.md +91 -0
  158. package/src/skf-analyze-source/references/step-auto-scope.md +208 -293
  159. package/src/skf-analyze-source/references/step-shape-detect.md +14 -12
  160. package/src/skf-analyze-source/references/unit-detection-heuristics.md +37 -42
  161. package/src/skf-audit-skill/SKILL.md +43 -51
  162. package/src/skf-audit-skill/assets/drift-report-template.md +27 -3
  163. package/src/skf-audit-skill/customize.toml +41 -20
  164. package/src/skf-audit-skill/references/constituent-freshness.md +91 -0
  165. package/src/skf-audit-skill/references/doc-drift.md +141 -0
  166. package/src/skf-audit-skill/references/headless-contract.md +29 -0
  167. package/src/skf-audit-skill/references/init.md +148 -210
  168. package/src/skf-audit-skill/references/re-index.md +96 -108
  169. package/src/skf-audit-skill/references/report.md +96 -33
  170. package/src/skf-audit-skill/references/semantic-diff.md +27 -18
  171. package/src/skf-audit-skill/references/severity-classify.md +79 -65
  172. package/src/skf-audit-skill/references/severity-rules.md +15 -6
  173. package/src/skf-audit-skill/references/structural-diff.md +75 -90
  174. package/src/skf-audit-skill/references/upstream-checkout.md +77 -0
  175. package/src/skf-audit-skill/scripts/render-drift-tables.py +685 -0
  176. package/src/skf-brief-skill/SKILL.md +36 -25
  177. package/src/skf-brief-skill/assets/description-voice-examples.md +1 -1
  178. package/src/skf-brief-skill/assets/scope-templates.md +17 -24
  179. package/src/skf-brief-skill/assets/skill-brief-schema.md +29 -15
  180. package/src/skf-brief-skill/customize.toml +48 -20
  181. package/src/skf-brief-skill/references/analyze-target.md +142 -125
  182. package/src/skf-brief-skill/references/confirm-brief.md +10 -8
  183. package/src/skf-brief-skill/references/draft-checkpoint.md +36 -17
  184. package/src/skf-brief-skill/references/gather-intent-ratify.md +68 -0
  185. package/src/skf-brief-skill/references/gather-intent.md +87 -182
  186. package/src/skf-brief-skill/references/headless-args.md +84 -16
  187. package/src/skf-brief-skill/references/health-check.md +1 -1
  188. package/src/skf-brief-skill/references/invocation-contract.md +18 -13
  189. package/src/skf-brief-skill/references/portfolio-similarity-check.md +1 -1
  190. package/src/skf-brief-skill/references/qmd-collection-registration.md +7 -10
  191. package/src/skf-brief-skill/references/scope-definition.md +123 -47
  192. package/src/skf-brief-skill/references/step-auto-brief.md +24 -80
  193. package/src/skf-brief-skill/references/step-auto-validate.md +20 -121
  194. package/src/skf-brief-skill/references/version-resolution.md +3 -2
  195. package/src/skf-brief-skill/references/write-brief.md +66 -57
  196. package/src/skf-campaign/SKILL.md +31 -34
  197. package/src/skf-campaign/assets/campaign-state-schema.json +25 -4
  198. package/src/skf-campaign/customize.toml +47 -16
  199. package/src/skf-campaign/references/campaign-contracts.md +39 -29
  200. package/src/skf-campaign/references/campaign-directive-spec.md +4 -2
  201. package/src/skf-campaign/references/health-check.md +7 -16
  202. package/src/skf-campaign/references/step-01-setup.md +46 -84
  203. package/src/skf-campaign/references/step-02-strategy.md +31 -30
  204. package/src/skf-campaign/references/step-03-pins.md +26 -18
  205. package/src/skf-campaign/references/step-04-provenance.md +24 -23
  206. package/src/skf-campaign/references/step-05-skill-loop.md +67 -48
  207. package/src/skf-campaign/references/step-06-batch.md +41 -34
  208. package/src/skf-campaign/references/step-07-capstone.md +40 -25
  209. package/src/skf-campaign/references/step-08-verify.md +28 -29
  210. package/src/skf-campaign/references/step-09-refine.md +29 -30
  211. package/src/skf-campaign/references/step-10-export.md +48 -36
  212. package/src/skf-campaign/references/step-11-maintenance.md +31 -34
  213. package/src/skf-campaign/references/step-resume.md +37 -68
  214. package/src/skf-campaign/scripts/campaign-deps.py +57 -18
  215. package/src/skf-campaign/scripts/campaign-parse-manifest.py +361 -54
  216. package/src/skf-campaign/scripts/campaign-provenance.py +96 -53
  217. package/src/skf-campaign/scripts/campaign-quality-gate.py +592 -0
  218. package/src/skf-campaign/scripts/campaign-render-batch.py +257 -49
  219. package/src/skf-campaign/scripts/campaign-render-kickoff.py +343 -50
  220. package/src/skf-campaign/scripts/campaign-report.py +204 -37
  221. package/src/skf-campaign/scripts/campaign-state.py +1128 -0
  222. package/src/skf-campaign/scripts/campaign-status.py +10 -74
  223. package/src/skf-campaign/scripts/campaign-validate-pins.py +30 -3
  224. package/src/skf-campaign/scripts/campaign-validate-state.py +34 -4
  225. package/src/skf-campaign/templates/campaign-brief-template.yaml +4 -5
  226. package/src/skf-campaign/templates/campaign-report-template.md +5 -1
  227. package/src/skf-campaign/templates/kickoff-template.md +0 -14
  228. package/src/skf-create-skill/SKILL.md +27 -20
  229. package/src/skf-create-skill/assets/compile-assembly-rules.md +6 -5
  230. package/src/skf-create-skill/assets/skill-sections.md +15 -5
  231. package/src/skf-create-skill/customize.toml +20 -8
  232. package/src/skf-create-skill/references/authoritative-files-protocol.md +41 -42
  233. package/src/skf-create-skill/references/batch-mode.md +81 -0
  234. package/src/skf-create-skill/references/ccc-index-check.md +27 -0
  235. package/src/skf-create-skill/references/compile.md +107 -29
  236. package/src/skf-create-skill/references/component-extraction.md +113 -91
  237. package/src/skf-create-skill/references/enrich.md +41 -23
  238. package/src/skf-create-skill/references/entry-points-by-hand.md +20 -0
  239. package/src/skf-create-skill/references/extract.md +200 -161
  240. package/src/skf-create-skill/references/extraction-patterns-by-hand.md +141 -0
  241. package/src/skf-create-skill/references/extraction-patterns-tracing.md +2 -2
  242. package/src/skf-create-skill/references/extraction-patterns.md +584 -196
  243. package/src/skf-create-skill/references/generate-artifacts.md +145 -93
  244. package/src/skf-create-skill/references/health-check.md +1 -1
  245. package/src/skf-create-skill/references/load-brief.md +53 -36
  246. package/src/skf-create-skill/references/relabel-rule.md +12 -0
  247. package/src/skf-create-skill/references/report.md +28 -59
  248. package/src/skf-create-skill/references/source-resolution-protocols.md +49 -155
  249. package/src/skf-create-skill/references/step-auto-shard.md +20 -93
  250. package/src/skf-create-skill/references/step-doc-rot.md +44 -60
  251. package/src/skf-create-skill/references/step-doc-sources.md +28 -19
  252. package/src/skf-create-skill/references/sub/ccc-discover.md +18 -7
  253. package/src/skf-create-skill/references/sub/fetch-docs.md +106 -59
  254. package/src/skf-create-skill/references/sub/fetch-temporal.md +53 -166
  255. package/src/skf-create-skill/references/tier-degradation-rules.md +18 -9
  256. package/src/skf-create-skill/references/validate.md +173 -99
  257. package/src/skf-create-skill/scripts/scan-doc-rot.py +232 -99
  258. package/src/skf-create-stack-skill/SKILL.md +29 -56
  259. package/src/skf-create-stack-skill/assets/metadata-contract.md +51 -0
  260. package/src/skf-create-stack-skill/assets/provenance-map-schema.md +15 -15
  261. package/src/skf-create-stack-skill/assets/stack-skill-template.md +23 -57
  262. package/src/skf-create-stack-skill/customize.toml +23 -12
  263. package/src/skf-create-stack-skill/references/compile-stack.md +57 -66
  264. package/src/skf-create-stack-skill/references/compose-mode-rules.md +24 -44
  265. package/src/skf-create-stack-skill/references/detect-integrations.md +92 -95
  266. package/src/skf-create-stack-skill/references/detect-manifests.md +46 -71
  267. package/src/skf-create-stack-skill/references/generate-output.md +138 -128
  268. package/src/skf-create-stack-skill/references/init.md +90 -32
  269. package/src/skf-create-stack-skill/references/integration-patterns.md +1 -17
  270. package/src/skf-create-stack-skill/references/invocation-contract.md +34 -0
  271. package/src/skf-create-stack-skill/references/manifest-patterns.md +32 -20
  272. package/src/skf-create-stack-skill/references/parallel-extract.md +112 -38
  273. package/src/skf-create-stack-skill/references/rank-and-confirm.md +57 -75
  274. package/src/skf-create-stack-skill/references/report.md +39 -33
  275. package/src/skf-create-stack-skill/references/validate.md +20 -39
  276. package/src/skf-drop-skill/SKILL.md +28 -51
  277. package/src/skf-drop-skill/customize.toml +44 -30
  278. package/src/skf-drop-skill/references/execute.md +79 -146
  279. package/src/skf-drop-skill/references/invocation-contract.md +64 -0
  280. package/src/skf-drop-skill/references/report.md +46 -30
  281. package/src/skf-drop-skill/references/select.md +118 -124
  282. package/src/skf-drop-skill/scripts/dir-sizes.py +54 -26
  283. package/src/skf-drop-skill/scripts/drop-roster.py +322 -0
  284. package/src/skf-export-skill/SKILL.md +40 -62
  285. package/src/skf-export-skill/assets/managed-section-format.md +14 -50
  286. package/src/skf-export-skill/assets/snippet-format.md +3 -1
  287. package/src/skf-export-skill/customize.toml +42 -13
  288. package/src/skf-export-skill/references/generate-snippet.md +54 -46
  289. package/src/skf-export-skill/references/health-check.md +2 -0
  290. package/src/skf-export-skill/references/invocation-contract.md +15 -0
  291. package/src/skf-export-skill/references/load-skill.md +88 -62
  292. package/src/skf-export-skill/references/manifest-rebuild.md +9 -10
  293. package/src/skf-export-skill/references/multi-skill-mode.md +4 -4
  294. package/src/skf-export-skill/references/orphan-context-detection.md +13 -5
  295. package/src/skf-export-skill/references/orphan-row-detection.md +31 -22
  296. package/src/skf-export-skill/references/package.md +15 -73
  297. package/src/skf-export-skill/references/preflight-snippet-root-probe.md +51 -70
  298. package/src/skf-export-skill/references/result-envelope.md +31 -16
  299. package/src/skf-export-skill/references/summary.md +41 -17
  300. package/src/skf-export-skill/references/token-report.md +4 -12
  301. package/src/skf-export-skill/references/update-context.md +118 -237
  302. package/src/skf-forger/SKILL.md +61 -37
  303. package/src/skf-forger/bmad-skill-manifest.yaml +4 -1
  304. package/src/skf-forger/customize.toml +43 -0
  305. package/src/skf-forger/references/pipeline-mode.md +73 -18
  306. package/src/skf-forger/scripts/forge-status.py +299 -0
  307. package/src/skf-forger/scripts/parse-pipeline.py +322 -54
  308. package/src/skf-forger/scripts/pipeline-gate.py +428 -0
  309. package/src/skf-forger/scripts/pipeline-journal.py +1052 -0
  310. package/src/skf-quick-skill/SKILL.md +54 -53
  311. package/src/skf-quick-skill/assets/skill-template.md +4 -2
  312. package/src/skf-quick-skill/customize.toml +51 -20
  313. package/src/skf-quick-skill/references/batch-mode.md +74 -21
  314. package/src/skf-quick-skill/references/compile.md +30 -31
  315. package/src/skf-quick-skill/references/ecosystem-check.md +7 -57
  316. package/src/skf-quick-skill/references/finalize.md +69 -18
  317. package/src/skf-quick-skill/references/halt-contract.md +41 -29
  318. package/src/skf-quick-skill/references/health-check.md +5 -3
  319. package/src/skf-quick-skill/references/quick-extract.md +114 -45
  320. package/src/skf-quick-skill/references/registry-resolution.md +9 -64
  321. package/src/skf-quick-skill/references/resolve-target.md +116 -66
  322. package/src/skf-quick-skill/references/write-and-validate.md +79 -40
  323. package/src/skf-refine-architecture/SKILL.md +43 -53
  324. package/src/skf-refine-architecture/customize.toml +49 -20
  325. package/src/skf-refine-architecture/references/compile.md +97 -54
  326. package/src/skf-refine-architecture/references/exit-codes.md +30 -0
  327. package/src/skf-refine-architecture/references/finding-storage.md +21 -0
  328. package/src/skf-refine-architecture/references/gap-analysis.md +101 -38
  329. package/src/skf-refine-architecture/references/improvements.md +14 -20
  330. package/src/skf-refine-architecture/references/init.md +98 -57
  331. package/src/skf-refine-architecture/references/issue-detection.md +32 -39
  332. package/src/skf-refine-architecture/references/refinement-rules.md +37 -48
  333. package/src/skf-refine-architecture/references/report.md +65 -54
  334. package/src/skf-refine-architecture/scripts/skf-check-preservation.py +1619 -0
  335. package/src/skf-rename-skill/SKILL.md +19 -54
  336. package/src/skf-rename-skill/customize.toml +32 -26
  337. package/src/skf-rename-skill/references/execute.md +230 -184
  338. package/src/skf-rename-skill/references/exit-codes.md +7 -7
  339. package/src/skf-rename-skill/references/health-check.md +1 -7
  340. package/src/skf-rename-skill/references/invocation-contract.md +25 -0
  341. package/src/skf-rename-skill/references/report.md +63 -52
  342. package/src/skf-rename-skill/references/select.md +197 -115
  343. package/src/skf-rename-skill/scripts/skf-validate-rename-name.py +161 -21
  344. package/src/skf-setup/SKILL.md +26 -26
  345. package/src/skf-setup/customize.toml +14 -10
  346. package/src/skf-setup/references/auto-index.md +50 -63
  347. package/src/skf-setup/references/ccc-index.md +29 -90
  348. package/src/skf-setup/references/detect-and-tier.md +58 -67
  349. package/src/skf-setup/references/health-check.md +2 -0
  350. package/src/skf-setup/references/invocation-contract.md +14 -0
  351. package/src/skf-setup/references/report.md +43 -166
  352. package/src/skf-setup/references/tier-rules.md +5 -5
  353. package/src/skf-setup/references/write-config.md +34 -57
  354. package/src/skf-test-skill/SKILL.md +17 -57
  355. package/src/skf-test-skill/assets/output-section-formats.md +33 -34
  356. package/src/skf-test-skill/customize.toml +27 -13
  357. package/src/skf-test-skill/references/coherence-check.md +134 -62
  358. package/src/skf-test-skill/references/coverage-check-tiers.md +35 -0
  359. package/src/skf-test-skill/references/coverage-check.md +217 -254
  360. package/src/skf-test-skill/references/detect-mode.md +5 -5
  361. package/src/skf-test-skill/references/external-validators.md +94 -82
  362. package/src/skf-test-skill/references/health-check.md +6 -7
  363. package/src/skf-test-skill/references/init.md +163 -88
  364. package/src/skf-test-skill/references/invocation-contract.md +66 -0
  365. package/src/skf-test-skill/references/migration-section-rules.md +5 -2
  366. package/src/skf-test-skill/references/report.md +162 -142
  367. package/src/skf-test-skill/references/score.md +80 -107
  368. package/src/skf-test-skill/references/scoring-rules.md +41 -155
  369. package/src/skf-test-skill/references/source-access-protocol.md +19 -92
  370. package/src/skf-test-skill/references/step-hard-gate.md +51 -33
  371. package/src/skf-test-skill/scripts/aggregate-coherence.py +218 -30
  372. package/src/skf-test-skill/scripts/build-result-context.py +287 -0
  373. package/src/skf-test-skill/scripts/check-metadata-coherence.py +37 -4
  374. package/src/skf-test-skill/scripts/combine-external-scores.py +23 -6
  375. package/src/skf-test-skill/scripts/compute-score.py +223 -45
  376. package/src/skf-test-skill/scripts/gap-ledger.py +1381 -0
  377. package/src/skf-test-skill/scripts/hard-gate.py +203 -0
  378. package/src/skf-test-skill/scripts/load-coverage-inputs.py +760 -0
  379. package/src/skf-test-skill/scripts/locate-export-segments.py +835 -0
  380. package/src/skf-test-skill/scripts/reconcile-coverage.py +273 -79
  381. package/src/skf-test-skill/scripts/score-signatures.py +459 -0
  382. package/src/skf-test-skill/scripts/stage-helper-payload.py +148 -0
  383. package/src/skf-test-skill/scripts/validate-inventory.py +311 -16
  384. package/src/skf-test-skill/scripts/verify-declared-numerator.py +127 -52
  385. package/src/skf-test-skill/templates/test-report-template.md +21 -15
  386. package/src/skf-update-skill/SKILL.md +38 -25
  387. package/src/skf-update-skill/customize.toml +27 -12
  388. package/src/skf-update-skill/references/detect-changes.md +233 -222
  389. package/src/skf-update-skill/references/gap-driven.md +336 -0
  390. package/src/skf-update-skill/references/health-check.md +31 -5
  391. package/src/skf-update-skill/references/init.md +250 -84
  392. package/src/skf-update-skill/references/invocation-contract.md +12 -0
  393. package/src/skf-update-skill/references/manual-section-rules.md +6 -23
  394. package/src/skf-update-skill/references/merge.md +180 -47
  395. package/src/skf-update-skill/references/re-extract.md +53 -262
  396. package/src/skf-update-skill/references/report.md +100 -35
  397. package/src/skf-update-skill/references/write.md +331 -149
  398. package/src/skf-update-skill/scripts/skf-new-file-diff.py +29 -7
  399. package/src/skf-verify-stack/SKILL.md +23 -42
  400. package/src/skf-verify-stack/assets/feasibility-report-template.md +11 -5
  401. package/src/skf-verify-stack/customize.toml +55 -22
  402. package/src/skf-verify-stack/references/coverage-patterns.md +17 -8
  403. package/src/skf-verify-stack/references/coverage.md +67 -64
  404. package/src/skf-verify-stack/references/exit-codes.md +21 -8
  405. package/src/skf-verify-stack/references/init.md +107 -62
  406. package/src/skf-verify-stack/references/integration-verification-rules.md +12 -13
  407. package/src/skf-verify-stack/references/integrations.md +106 -65
  408. package/src/skf-verify-stack/references/report.md +59 -42
  409. package/src/skf-verify-stack/references/requirements.md +32 -9
  410. package/src/skf-verify-stack/references/synthesize.md +53 -39
  411. package/src/skf-verify-stack/scripts/skf-coverage-tally.py +398 -52
  412. package/src/skf-verify-stack/scripts/skf-previous-report.py +330 -0
  413. package/src/skf-verify-stack/scripts/skf-report-delta.py +453 -49
  414. package/src/skf-verify-stack/scripts/skf-verdict-rollup.py +240 -27
  415. package/tools/cli/commands/install.js +11 -4
  416. package/tools/cli/commands/status.js +15 -3
  417. package/tools/cli/commands/update.js +11 -4
  418. package/tools/cli/lib/tool-check.js +320 -0
  419. package/tools/cli/lib/version-check.js +22 -9
  420. package/tools/cli/skf-cli.js +4 -1
  421. package/.gitattributes +0 -16
  422. package/.nvmrc +0 -1
  423. package/docs/_internal/RELEASING.md +0 -679
  424. package/release-audits/v1.0.0-launch-audit.md +0 -728
  425. package/src/skf-audit-skill/references/step-doc-drift.md +0 -177
  426. package/src/skf-brief-skill/references/headless-source-authority-detection.md +0 -26
  427. package/src/skf-campaign/manifest.yaml +0 -15
  428. package/src/skf-create-skill/assets/tessl-dismissal-rules.md +0 -106
  429. package/src/skf-create-skill/references/ecosystem-check.md +0 -74
  430. package/src/skf-drop-skill/references/headless-contract.md +0 -18
  431. package/src/skf-update-skill/references/merge-conflict-rules.md +0 -15
  432. package/src/skf-update-skill/references/remote-source-resolution.md +0 -98
  433. package/src/skf-update-skill/references/validate.md +0 -124
  434. package/tools/validate-docs-drift.js +0 -233
  435. package/tools/validate-docs-links.js +0 -665
@@ -1,8 +1,8 @@
1
1
  # DO NOT EDIT -- overwritten on every update.
2
2
  #
3
3
  # Workflow customization surface for skf-create-skill.
4
- # Team overrides: _bmad/custom/skf-create-skill.toml (under {project-root})
5
- # Personal overrides: _bmad/custom/skf-create-skill.user.toml (under {project-root})
4
+ # Team overrides: {project-root}/_bmad/custom/skf-create-skill.toml
5
+ # Personal overrides: {project-root}/_bmad/custom/skf-create-skill.user.toml
6
6
 
7
7
  [workflow]
8
8
 
@@ -23,7 +23,7 @@ activation_steps_prepend = []
23
23
  activation_steps_append = []
24
24
 
25
25
  # Persistent facts the workflow keeps in mind for the whole run
26
- # (extraction style, compilation guardrails, tessl review preferences).
26
+ # (extraction style, compilation guardrails).
27
27
  # Overrides append.
28
28
  #
29
29
  # Each entry is either:
@@ -31,17 +31,29 @@ activation_steps_append = []
31
31
  # - a file reference prefixed with `file:`, e.g.
32
32
  # "file:{project-root}/docs/create-policy.md" (globs supported; file
33
33
  # contents are loaded and treated as facts).
34
+ #
35
+ # The bundled entry below loads every project-context.md under
36
+ # {project-root} (the BMad project context) as facts for each brief.
37
+ # Overrides append, so no override can delete it. To drop it, add the same
38
+ # entry with a leading `!` in {project-root}/_bmad/custom/skf-create-skill.toml:
39
+ # persistent_facts = ["!file:{project-root}/**/project-context.md"]
40
+ # The workflow then skips both (SKILL.md On Activation step 3); a `!` entry
41
+ # drops any entry it names this way.
34
42
 
35
43
  persistent_facts = [
36
44
  "file:{project-root}/**/project-context.md",
37
45
  ]
38
46
 
39
- # Pipeline-integration hook invoked after the final report (step 8) and the
40
- # result JSON / metadata.json are finalized. The command is called as:
47
+ # Pipeline-integration hook invoked by step 8 (report) once a brief's result
48
+ # contract is written, after its compilation report. The value is a shell
49
+ # command, run from {project-root}, not an agent instruction: a shell cannot
50
+ # run a skill such as test-skill or export-skill. It is called as:
41
51
  # <on_complete> --result-path=<{forge_version}/create-skill-result-latest.json>
42
- # Useful for Slack notifications, dashboard ingest, CI hooks, or chaining a
43
- # downstream skill (TS test-skill, EX export). Failures are logged to
44
- # workflow_warnings[] but never fail the workflow.
52
+ # Under --batch it runs once per brief, each time with that brief's result
53
+ # file; a brief that halts, or whose result file was not written, gets no
54
+ # call. Useful for a Slack or email notifier, dashboard ingest, a CI script
55
+ # or a git-add wrapper. A failure is reported on its own line and never
56
+ # fails the brief.
45
57
  #
46
58
  # Empty string = no-op (default).
47
59
 
@@ -2,11 +2,13 @@
2
2
 
3
3
  ## Overview
4
4
 
5
- Loaded on demand when step 3's `### 2a. Discovered Authoritative Files Protocol` sub-step runs.
5
+ Loaded on demand when step 3's `### 2a. Discovered Authoritative Files Protocol` sub-step runs, after `### 2b. Resolve Source Access` has resolved the source to a local tree.
6
6
 
7
7
  **Skip this protocol entirely if `source_type: "docs-only"`** — there is no source tree to scan.
8
8
 
9
- Before resolving source access for extraction, scan the source tree for **authoritative AI documentation files** that the brief's scope filters excluded. Project authors increasingly add files specifically written to steer AI assistants (`llms.txt`, `AGENTS.md`, `.cursorrules`, etc.), and these files often contain the **canonical** install command, quick-start, or architecture summary — information that nowhere else in the source tree provides. A brief authored from a scan of `src/**` will frequently exclude these files without the author realizing they exist.
9
+ **Skip it too when `source_root` is still a remote URL** (a Quick-tier remote source, which §2b never clones, or a remote source §2b could not read into a tree): step 3 §2a's remote source guard skips the scan with a notice, because the helper below walks a local directory and refuses a URL.
10
+
11
+ Once §2b has resolved source access, scan the resolved source tree (the local source, or the private tree §2b read a remote one into) for **authoritative AI documentation files** that the brief's scope filters excluded. Project authors increasingly add files specifically written to steer AI assistants (`llms.txt`, `AGENTS.md`, `.cursorrules`, etc.), and these files often contain the **canonical** install command, quick-start, or architecture summary: information that nowhere else in the source tree provides. A brief authored from a scan of `src/**` will frequently exclude these files without the author realizing they exist.
10
12
 
11
13
  This protocol detects such files, prompts the user, and records the decision in the brief so future runs (re-create, update, audit) honor it.
12
14
 
@@ -14,16 +16,16 @@ This protocol detects such files, prompts the user, and records the decision in
14
16
 
15
17
  ## Procedure
16
18
 
17
- 1. **Resolve, scan, classify, and load previews in one call.** The helper handles the source-tree walk (pruning `node_modules`, `dist`, `.git`, etc.), case-insensitive basename matching, scope-filter diff (with `**`-recursive-glob support), amendment reconciliation (most-recent action wins), preview load (first 20 lines), and SHA-256 hashing:
19
+ 1. **Resolve, scan, classify, and load previews in one call.** Resolve `{resolveAuthoritativeFilesHelper}` ← first existing path in `{resolveAuthoritativeFilesProbeOrder}` (step 3's frontmatter); if neither exists, **HARD HALT** (exit code 3, `helper-missing`, phase `extract`; stage `{run_dir}/halt.json` per the Workflow Rules and run `uv run {emitEnvelopeHelper} emit-halt --workflow skf-create-skill --run-dir "{run_dir}" --target stderr < "{run_dir}/halt.json"`): "Cannot scan for authoritative files: skf-resolve-authoritative-files.py is missing. Re-install SKF, then re-run create-skill." The helper handles the source-tree walk (pruning `node_modules`, `dist`, `.git`, etc.), case-insensitive basename matching, scope-filter diff (with `**`-recursive-glob support), amendment reconciliation (most-recent action wins), preview load (first 20 lines), and SHA-256 hashing:
18
20
 
19
21
  ```bash
20
22
  uv run {resolveAuthoritativeFilesHelper} resolve \
21
- --source-root {source_root} \
22
- --brief {forge_data_folder}/{skill_name}/skill-brief.yaml \
23
+ --source-root "{source_root}" \
24
+ --brief "{brief_path}" \
23
25
  [--preview-lines 20]
24
26
  ```
25
27
 
26
- The helper emits one envelope with three buckets:
28
+ `{source_root}` is the local tree §2b resolved: the local source, or the private tree of a remote one, and `{brief_path}` the `skill-brief.yaml` step 1 loaded. The helper emits one envelope with three buckets:
27
29
 
28
30
  ```json
29
31
  {
@@ -47,17 +49,18 @@ This protocol detects such files, prompts the user, and records the decision in
47
49
  {"path": "...", "heuristic": "...", "size_bytes": N,
48
50
  "line_count": N, "content_hash": "sha256:...",
49
51
  "preview": "<first N lines>",
50
- "excluded_by_pattern": "<glob>"|"not matched by any scope.include"}
52
+ "excluded_by_pattern": "<glob>"|"not matched by any scope.include",
53
+ "prior_action": null|"deferred-headless"}
51
54
  ]
52
55
  }
53
56
  ```
54
57
 
55
58
  2. **Apply the helper's classification:**
56
59
 
57
- - **`already_in_scope[]`** — file is in scope and not skipped. **Remove the path from §2's filtered file list** and append the record to in-context `promoted_docs[]`. No prompt — authoritative docs must never reach §4 code extraction even when scope.include matches.
60
+ - **`already_in_scope[]`**: the file is in scope and not skipped. Append the record to in-context `promoted_docs[]`, and remove the path from §2's filtered file list when §2 built one (at Forge tier and above the recipe runner reads the brief itself and builds no list). No prompt: authoritative docs must never reach §4 code extraction even when scope.include matches.
58
61
  - **`pre_decided[]` with `prior_action: "promoted"`** — amendment says promoted; **append to `promoted_docs[]`** using the helper-supplied hash/size/lines. Deterministic replay path.
59
62
  - **`pre_decided[]` with `prior_action: "skipped"`** — user previously declined. Do nothing. Move on.
60
- - **`unresolved[]`** — proceed to step 3 below (user prompt).
63
+ - **`unresolved[]`**: proceed to step 3 below (user prompt). A `prior_action` of `deferred-headless` means an earlier headless run met the file and left the decision to the next interactive run.
61
64
 
62
65
  3. **Prompt.** Present each `unresolved[]` candidate to the user. Use the helper's `preview`, `size_bytes`, `line_count`, and `excluded_by_pattern` fields verbatim so the prompt reports facts rather than recomputing them:
63
66
 
@@ -79,56 +82,52 @@ This protocol detects such files, prompts the user, and records the decision in
79
82
  [U] Update — halt this run and return to skf-brief-skill to refine scope
80
83
  ```
81
84
 
82
- 4. **Headless mode (`{headless_mode}` is true):** auto-select `[S] Skip` for every candidate. Record amendment entries with `action: "skipped"` and `reason: "headless: no user to prompt"`. A non-interactive run must never silently promote files into scope — the decision requires a human.
85
+ 4. **GATE [default: defer]**: in headless mode (`{headless_mode}` is true), promote nothing and decline nothing: whether a file enters scope is a person's decision, so this run leaves every `unresolved[]` candidate out of extraction and defers it to the next interactive run, which asks. For each candidate:
86
+ - Record one auto-decision per path, per the Workflow Rules: stage `{"step": "extract", "gate": "authoritative-file:{path}", "decision": "deferred-headless", "rationale": "headless mode: no person to decide whether {path} enters the scope", "timestamp": "{ISO}"}` as `{run_dir}/decision.json` and run `uv run {emitEnvelopeHelper} record --workflow skf-create-skill --run-dir "{run_dir}" --decision < "{run_dir}/decision.json"`. The path in the gate keeps several candidates from collapsing into one row.
87
+ - When its `prior_action` is null, record the deferral in the brief with step 5's **Write the decision** call, with one amendment per such candidate: `action: "deferred-headless"`, `reason: "headless: no person to decide; the next interactive run asks"`, `heuristic: {basename}`, `date: {today ISO}`, `workflow: "skf-create-skill"`. The helper keeps a `deferred-headless` path in `unresolved[]`, never in `pre_decided[]`. A candidate whose `prior_action` is already `deferred-headless` is not written again.
83
88
 
84
89
  5. **Apply decision:**
85
90
 
91
+ **Write the decision** to the brief at once, so a crashed run still leaves it recorded and a re-run replays it instead of asking again. Resolve `{writeSkillBriefHelper}` ← first existing path in `{writeSkillBriefProbeOrder}` and, from `{project-root}`, run `amend`: it reads the brief again, appends the paths in `include` to `scope.include` and the entries in `amendments` to `scope.amendments`, refuses an amendment that breaks the brief schema, keeps the previous brief as `{brief_path}.bak` and writes the new one atomically:
92
+
93
+ ```bash
94
+ uv run {writeSkillBriefHelper} amend --target "{brief_path}" <<'SKF_BRIEF_DECISION'
95
+ {"include": ["{path}"], "amendments": [{"path": "{path}", "action": "promoted|skipped|deferred-headless", "reason": "{reason}", "heuristic": "{basename}", "date": "{today ISO}", "workflow": "skf-create-skill"}]}
96
+ SKF_BRIEF_DECISION
97
+ ```
98
+
99
+ Pass `include` for a promoted path only. The helper appends it only when `scope.include` is not empty: an empty include already covers every file, and appending one path would narrow the scope to it; the `promoted` amendment replays the decision either way, through the helper's `pre_decided[]`. When the command exits non-zero or no path resolves, warn "The decision on `{path}` was not saved to the brief ({its stderr}): the next run asks again." and continue.
100
+
86
101
  - **[P] Promote:**
87
- 1. **Do not add the path to the filtered file list from §2.** Authoritative documentation files are not code — they must not go through the AST extraction pipeline in §4, which would silently produce no exports (ghost entries). Instead, add the path to a new in-context list `promoted_docs[]` with `{path, heuristic, size_bytes, line_count, content_hash}`. Compute the SHA-256 content hash of the file now.
88
- 2. Append to `brief.scope.include`: add the exact `candidate.path` as a literal glob (no wildcards — the amendment targets this specific file). This write ensures that a re-run of `skf-create-skill` against the amended brief sees the path in scope and skips re-prompting.
89
- 3. Append to `brief.scope.amendments[]` a new entry with `action: "promoted"`, `path: candidate.path`, `reason: {user-provided one-sentence reason or auto-generated "authoritative AI docs — matched heuristic {basename}"}`, `heuristic: {basename}`, `date: {today ISO}`, `workflow: "skf-create-skill"`.
90
- 4. **Write the amended brief back to disk immediately** at `{forge_data_folder}/{skill_name}/skill-brief.yaml`. Immediate write (not deferred to step 7) ensures a crashed run still leaves the amendment recorded. Preserve all other brief fields and formatting. **Use atomic write + backup:** before writing, copy the original brief to `{forge_data_folder}/{skill_name}/skill-brief.yaml.bak` (overwriting any prior `.bak` — the most recent pre-amendment snapshot is the useful one). Then pipe the amended YAML through the shared atomic writer so a crash mid-write cannot corrupt the brief:
91
-
92
- ```bash
93
- # 1. Backup
94
- cp {forge_data_folder}/{skill_name}/skill-brief.yaml \
95
- {forge_data_folder}/{skill_name}/skill-brief.yaml.bak
96
-
97
- # 2. Atomic write (stdin → tmp → fsync → rename)
98
- cat <<'AMENDED_YAML' | python3 {atomicWriteHelper} write \
99
- --target {forge_data_folder}/{skill_name}/skill-brief.yaml
100
- {amended brief YAML}
101
- AMENDED_YAML
102
- ```
103
-
104
- The helper stages into `{brief}.skf-tmp`, fsyncs, then `os.replace()`s — readers never see a half-written brief.
105
- 5. Display: "**Promoted `{path}`** — tracked as documentation file, amendment recorded."
102
+ 1. **Do not hand the path to §4.** Authoritative documentation files are not code: the AST extraction pipeline would silently produce no exports (ghost entries). Add the path to a new in-context list `promoted_docs[]` with `{path, heuristic, size_bytes, line_count, content_hash}`, taking the values the helper reported, and remove it from §2's filtered file list when §2 built one.
103
+ 2. **Write the decision** with `include: ["{path}"]` and an amendment with `action: "promoted"`, `reason`: the user's one-sentence reason, else "authoritative AI docs, matched heuristic {basename}".
104
+ 3. Display: "**Promoted `{path}`**: tracked as documentation file, amendment recorded."
106
105
 
107
106
  - **[S] Skip:**
108
- 1. Do not modify `scope.include` or `scope.exclude`.
109
- 2. Append to `brief.scope.amendments[]` a new entry with `action: "skipped"`, `path: candidate.path`, `reason: {user-provided reason or auto-generated "user declined promotion at create-skill §2a"}`, `heuristic: {basename}`, `date: {today ISO}`, `workflow: "skf-create-skill"`.
110
- 3. **Write the amended brief back to disk** so future runs do not re-prompt. Use the same backup-then-atomic-write pattern as the [P] Promote path (copy to `skill-brief.yaml.bak` first, then pipe through `skf-atomic-write.py write --target {brief_path}`).
111
- 4. Display: "**Skipped `{path}`** — decision recorded in amendments."
107
+ 1. Leave `scope.include` and `scope.exclude` as they are.
108
+ 2. **Write the decision** with no `include` and an amendment with `action: "skipped"`, `reason`: the user's reason, else "user declined promotion at create-skill §2a".
109
+ 3. Display: "**Skipped `{path}`**: decision recorded in amendments."
112
110
 
113
111
  - **[U] Update:**
114
- 1. Halt the workflow immediately.
115
- 2. Display: "**Halting create-skill.** Re-run `skf-brief-skill` to refine the scope filters for `{skill_name}`, then re-run `skf-create-skill`. Decisions for previously prompted candidates were already persisted to the brief; the current candidate was not written."
116
- 3. Exit with status `halted-for-brief-refinement`.
112
+ 1. When `{source_tree}` is set, first run `uv run {sourceTreeHelper} close --tree "{source_tree}"` from `{project-root}` and go on whatever it prints: the scan read the tree §2b made, and nothing reads it after this halt.
113
+ 2. **HARD HALT** (exit code 6, `halted-for-brief-refinement`, phase `extract`; stage `{run_dir}/halt.json` per the Workflow Rules and run `uv run {emitEnvelopeHelper} emit-halt --workflow skf-create-skill --run-dir "{run_dir}" --target stderr < "{run_dir}/halt.json"`): "**Halting create-skill.** Re-run `skf-brief-skill` to refine the scope filters for `{skill_name}`, then re-run `skf-create-skill`. Decisions for previously prompted candidates were already persisted to the brief; the current candidate was not written."
117
114
 
118
115
  6. **Summary.** After all candidates are resolved (or none were found), display a one-line summary:
119
116
 
120
- - `"Authoritative files scan: {N} candidates, {P} promoted, {S} skipped, {A} pre-decided from amendments."`
117
+ - `"Authoritative files scan: {N} candidates, {P} promoted, {S} skipped, {D} left for an interactive run, {A} pre-decided from amendments."`
121
118
  - If N = 0: `"Authoritative files scan: no candidates."`
122
119
 
123
- **Record for evidence report:** `authoritative_files_scan: {candidates: N, promoted: P, skipped: S, pre_decided: A, decisions: [{path, action, heuristic, reason}]}` — step 7 includes this in `evidence-report.md`.
120
+ **Record for evidence report:** `authoritative_files_scan: {candidates: N, promoted: P, skipped: S, deferred: D, pre_decided: A, decisions: [{path, action, heuristic, reason}]}`. Step 3 §5 writes it and `promoted_docs[]` into the extraction inventory, and step 5 writes it into `evidence-report.md`.
121
+
122
+ When step 3 §2a's remote source guard skipped the scan, the record is `authoritative_files_scan: {not_scanned: "remote source not cloned"}` instead (its own key, apart from the `skipped` count of candidates above), and step 6 lists that skip under the evidence report's Remaining Warnings.
124
123
 
125
124
  ## How promoted docs reach the provenance map
126
125
 
127
126
  Promoted docs do not flow through §4 code extraction. Instead:
128
127
 
129
- 1. §2a populates the in-context `promoted_docs[]` list with content hashes.
130
- 2. **Step-05 §6** (provenance-map assembly) reads `promoted_docs[]` and emits one `file_entries[]` entry per promoted doc with `file_type: "doc"`, `extraction_method: "promoted-authoritative"`, `confidence: "T1-low"`, and the pre-computed `content_hash`.
131
- 3. **Step-07 §2** does not copy doc files into the skill package (unlike scripts and assets). The source file remains at its original path; only the provenance map tracks it. Future audit and update workflows compare against this tracking entry via content hash — no file copy is required because the intent is drift detection on the *source*, not bundling documentation into the skill output.
128
+ 1. §2a populates the `promoted_docs[]` list with content hashes, which step 3 §5 writes into the extraction inventory.
129
+ 2. **Step-05 §6** (provenance-map assembly) reads `promoted_docs[]` from the inventory and emits one `file_entries[]` entry per promoted doc with `file_type: "doc"`, `extraction_method: "promoted-authoritative"`, `confidence: "T1-low"`, and the pre-computed `content_hash`.
130
+ 3. **Step 7's promotion** does not copy doc files into the skill package (unlike scripts and assets). The source file remains at its original path; only the provenance map tracks it. Future audit and update workflows compare against this tracking entry via content hash. No file copy is required, because the intent is drift detection on the *source*, not bundling documentation into the skill output.
132
131
 
133
132
  **Re-running `skf-create-skill`** reads the amended brief. Files with `action: "promoted"` amendments already appear in `scope.include`, but §2a still runs — it detects the file is in scope AND has an existing amendment, and takes the "pre-decided" silent path. The `promoted_docs[]` list is rebuilt on each run by scanning amendments with `action: "promoted"` (this is the deterministic replay path).
134
133
 
@@ -139,4 +138,4 @@ Zero code changes required in consumer workflows:
139
138
  - **`skf-update-skill`** reads `provenance-map.json`. Promoted docs appear as `file_entries[]` entries. Update-skill Category D (script/asset file changes) iterates `file_entries` and compares content hashes — this works identically for `file_type: "doc"` entries, giving drift detection for free.
140
139
  - **`skf-audit-skill`** scans files from `provenance-map.json`. The re-index builds its list from `entries[].source_file ∪ file_entries[].source_file`, so promoted doc paths are naturally included in the audit scan.
141
140
 
142
- The brief is the single source of truth for authored scope intent. The provenance map is the single source of truth for extracted state. `scope.amendments[]` is the bridge that records when those two intentionally diverged. `promoted_docs[]` is the in-memory handoff from §2a to step 5 §6; it is not persisted — the persisted form is the `file_entries[]` list in provenance-map.json.
141
+ The brief is the single source of truth for authored scope intent. The provenance map is the single source of truth for extracted state. `scope.amendments[]` is the bridge that records when those two intentionally diverged. `promoted_docs[]` is the handoff from §2a to step 5 §6, through the extraction inventory; the published form is the `file_entries[]` list in provenance-map.json.
@@ -0,0 +1,81 @@
1
+ ---
2
+ nextStepFile: 'load-brief.md'
3
+ healthCheckStepFile: 'health-check.md'
4
+ # Resolve `{quickBatchHelper}` to the first existing path. It keeps the
5
+ # batch on disk: §1 starts it, §2 hands out each brief, §3 records how each
6
+ # one ended and §4 ends the batch. If neither path exists, §1 halts before
7
+ # any brief compiles.
8
+ quickBatchProbeOrder:
9
+ - '{project-root}/_bmad/skf/shared/scripts/skf-quick-batch.py'
10
+ - '{project-root}/src/shared/scripts/skf-quick-batch.py'
11
+ # HARD HALT helper (Execution).
12
+ emitEnvelopeProbeOrder:
13
+ - '{project-root}/_bmad/skf/shared/scripts/skf-emit-result-envelope.py'
14
+ - '{project-root}/src/shared/scripts/skf-emit-result-envelope.py'
15
+ ---
16
+
17
+ <!-- Config: communicate in {communication_language}. -->
18
+
19
+ # Batch Mode
20
+
21
+ With `--batch`, create-skill compiles every brief the paths after the flag name, one after another: each path is a `skill-brief.yaml`, or a folder whose `skill-brief.yaml` files (at any depth, hidden folders left out) are compiled; with no path, the briefs under `{forge_data_folder}`. `skf-quick-batch.py` keeps the batch in its run folder, never only in context: it checks every brief with the brief schema validator before the first one compiles, hands out each brief in turn, records how each one ended, and computes the counts, the status and the exit code. A HARD HALT ends its brief, not the batch.
22
+
23
+ ## Execution
24
+
25
+ Resolve `{quickBatchHelper}` ← the first existing path in `{quickBatchProbeOrder}`, and `{emitEnvelopeHelper}`, which every HARD HALT here emits through, ← the first existing path in `{emitEnvelopeProbeOrder}` when it is not bound. The helper names the batch run folder, `{batch_dir}`, after the briefs: the same briefs always get the same folder, so a batch a session ended mid-way is found again (run `--batch` with the same briefs and it goes on with the brief it was working on, which compiles again from the start), and a batch of other briefs, from another terminal, never touches it. After a compaction, `{batch_dir}` is the parent folder of the brief's `{run_dir}`, and §1's `start` run again with the same briefs prints it without changing the batch.
26
+
27
+ ### 1. Start the Batch
28
+
29
+ ```bash
30
+ uv run {quickBatchHelper} start --briefs {batch_paths} --run-root "{project-root}/_bmad-output/.skf-run"
31
+ ```
32
+
33
+ `{batch_paths}` is each path given to `--batch`, quoted, or `"{forge_data_folder}"` when none was given. The helper finds the briefs and checks each one, and records each brief the validator refuses as failed, with its `halt_reason` (`brief-missing`, `brief-malformed` or `brief-invalid`) and the validator's first message, before any brief compiles; a brief whose `name` an earlier brief already has is refused the same way (`brief-invalid`), since both would compile into one skill folder. Bind `{batch_dir}` ← its `batch_dir`. When On Activation step 3 kept a `{customization_resolver_unavailable}` reason, write `customization_resolver_unavailable: {customization_resolver_unavailable}` to `{batch_dir}/resolver-warning.txt` with a file write, never `echo`: load-brief.md §0 records it in each brief's sink, after a compaction too. Display the plan: "**Batch:** {targets_total} briefs, {targets_total minus the `rejected` count} to compile." and, for each `rejected` entry, "Not compiled: `{target}`: {message}". When `resumed` is true, add "Resuming the batch: {recorded} briefs already ended."
34
+
35
+ If it exits non-zero, no brief compiles: the `halt_reason` of its stderr JSON names the halt. Display "**The batch cannot start:** {its `message`, or: skf-quick-batch.py is missing, re-install SKF}", and stop:
36
+
37
+ - `brief-missing`, no brief under the paths: **HARD HALT** (exit code 2, `brief-missing`, phase `batch-mode`; emit with nothing to stage in, below).
38
+ - `helper-missing`, the validator cannot load, or no path in `{quickBatchProbeOrder}` exists: **HARD HALT** (exit code 3, `helper-missing`, phase `batch-mode`; emit with nothing to stage in, below).
39
+ - `write-failed`, the batch folder cannot be written, or holds an unfinished batch of other briefs, which start never deletes: **HARD HALT** (exit code 4, `write-failed`, phase `batch-mode`; emit with nothing to stage in, below).
40
+
41
+ No run folder holds a payload yet, so the halt's envelope comes from the command alone. Every halt of this file emits this way, with the reason it gives:
42
+
43
+ ```bash
44
+ uv run {emitEnvelopeHelper} emit-halt --workflow skf-create-skill --target stderr <<'SKF_JSON'
45
+ {"phase": "batch-mode", "halt_reason": "<the halt_reason>", "reason": "The batch cannot start: <that message, one line>", "summary": {"halt_reason": "<the halt_reason>", "evidence_report": null}}
46
+ SKF_JSON
47
+ ```
48
+
49
+ ### 2. Take the Next Brief
50
+
51
+ ```bash
52
+ uv run {quickBatchHelper} next --run-dir "{batch_dir}"
53
+ ```
54
+
55
+ - **`"status": "next"`**: display the `start` event the helper printed on stderr. Bind `{run_dir}` ← its `run_dir`, the brief's own run folder, created empty, and `{brief_path}` ← its `target`. Nothing else carries over from the previous brief: its source, tree, extraction, staged skill and summary values all start empty. Then load, read in full and execute `{nextStepFile}`: steps 1 to 8 run for this brief.
56
+ - **`"status": "record"`**: brief `batch` ended, its payload staged, before §3 recorded it (a compaction came between its envelope and §3): go to §3 with that `batch`, never compiling it again.
57
+ - **`"status": "done"`**: no brief is pending. Go to §4.
58
+
59
+ If it exits non-zero (the brief's run folder cannot be created, or the batch file is gone or unreadable), the batch cannot go on: display "**The batch stopped:** {its `message`}" and **HARD HALT** (exit code 4, `write-failed`, phase `batch-mode`; emit with nothing to stage in, as §1 does, with the reason "The batch stopped: <its message>").
60
+
61
+ ### 3. Record the Brief
62
+
63
+ Every brief ends here: step 8 §6 sends a finished brief here, and every HARD HALT of steps 1 to 7 returns here after its envelope (each stage's Rules say so). Control returns here even when the step that ended the brief reads as the end of the run. Record it:
64
+
65
+ ```bash
66
+ uv run {quickBatchHelper} record --run-dir "{batch_dir}" --batch {batch} --target stderr
67
+ ```
68
+
69
+ `{batch}` is the number §2's `next` printed. The helper reads how the brief ended from what its run folder staged for the emitter (`halt.json`, or step 8's `result-context.json`), appends the outcome to the batch file, removes the run folder of a brief that finished (a halted brief keeps its folder for a look), and prints the brief's `done` or `fail` event on stderr: display it verbatim. Then go back to §2. If it exits non-zero, its `message` names what is missing: stage the payload the brief ended with and record again, once. If it exits non-zero a second time (the batch file cannot be written, or a `halt_reason` maps to no exit code), the outcome cannot be kept: display "**The batch stopped:** {its `message`}" and **HARD HALT** (exit code 4, `write-failed`, phase `batch-mode`; emit with nothing to stage in, as §1 does, with the reason "The batch stopped: <its message>").
70
+
71
+ ### 4. Batch Summary
72
+
73
+ ```bash
74
+ uv run {quickBatchHelper} summarize --run-dir "{batch_dir}" --output-dir "{skills_output_folder}/_batch" --target stderr
75
+ ```
76
+
77
+ The helper counts the briefs, sets the batch status and exit code, writes the summary to `{skills_output_folder}/_batch/create-skill-batch-{YYYYMMDD-HHmmss}.json` and its `create-skill-batch-latest.json` copy (`skill`, `mode`, `status`, `timestamp`, `input_briefs`, `targets_total`, `succeeded`, `failed`, `fail_fast_triggered`, `exit_code`, and `results[]`, one per brief with its `batch`, `target`, `status`, `exit_code`, `skill_package` and `error_code`), removes the batch run folder when no brief failed, and prints the `batch_summary` event on stderr: display it verbatim, then "Batch complete: {succeeded} of {targets_total} briefs compiled." and, when `failed` is above 0, the `target` and `error_code` of each failed `results[]` entry of the summary file.
78
+
79
+ Then load, read in full and execute `{healthCheckStepFile}`: the health check runs once per batch, here. The batch ends with the event's `exit_code`: 0 when every brief finished, else the highest exit code among the briefs that failed.
80
+
81
+ If `summarize` exits non-zero (a brief is still pending, or the batch file is gone or unreadable), the health check does not run: display "**The batch stopped:** {its `message`}" and **HARD HALT** (exit code 4, `write-failed`, phase `batch-mode`; emit with nothing to stage in, as §1 does, with the reason "The batch stopped: <its message>"). The summary files may be missing then, but each brief's own result contract is in its `{forge_version}`.
@@ -0,0 +1,27 @@
1
+ # CCC Index Check
2
+
3
+ Step 3 §2b (deferred ccc discovery on SKF's workspace clone) and step 7 §6b (the index the skill registers) load this file after they run `ccc index`. It waits for a running pass, checks that the source language was indexed, and repairs the index settings when it was not. The caller binds:
4
+
5
+ - `{ccc_root}`: the folder the index belongs to. ccc takes no path argument, so every ccc command below runs as `cd "{ccc_root}" && ccc ...`.
6
+ - `{ccc_settings_owner}`: `skf` when `{ccc_root}` is SKF's workspace clone of a remote source, whose `settings.yml` SKF edits only through `{mergeCccExclusionsHelper}`; `user` when `{ccc_root}` is the user's own source folder, whose `settings.yml` SKF never edits.
7
+
8
+ `{mergeCccExclusionsHelper}` is the first existing path in the caller's `mergeCccExclusionsProbeOrder`; run it from `{project-root}`.
9
+
10
+ ## 1. Wait for the Pass
11
+
12
+ Run `cd "{ccc_root}" && ccc status`. If it prints an `Indexing in progress:` line, a pass is still running and the counts below it are not final: run `cd "{ccc_root}" && ccc index` again, which waits for the running pass to finish and then makes a quick incremental pass, then run `ccc status` again. If the line is still there after 3 such runs, return **index unverified** to the caller and skip §2 and §3.
13
+
14
+ ## 2. Check the Languages
15
+
16
+ Once the line is gone, read the `Languages:` breakdown: a non-zero `Chunks`/`Files` total is not sufficient. Confirm the source's primary language (`{brief.language}`) reports a non-trivial chunk count. An index dominated by `markdown`/config chunks with the source language absent or near-zero means the source code was never indexed, and searches over it return nothing useful. When the source language is there, return **verified**.
17
+
18
+ ## 3. Repair
19
+
20
+ When the source language is absent, apply these repairs in order, stopping at the first one after which `Languages:` shows the source language:
21
+
22
+ 1. **No project of its own:** `{ccc_root}/.cocoindex_code/settings.yml` is missing and the `Project:` line of `ccc status` names another folder, so ccc indexed an enclosing project. With `{ccc_settings_owner}` `skf`, run `uv run {mergeCccExclusionsHelper} --clone-root "{ccc_root}"`: it runs `ccc init -f` there and adds the standard build and dependency exclusions. With `user`, run `cd "{ccc_root}" && ccc init -f`. Then run `ccc index`, then run `ccc status` and check `Languages:` again.
23
+ 2. **Language not included:** ccc indexes only the file types listed in `include_patterns`, and its default list leaves some languages out (Elixir's `.ex`, for example). Take the extensions of the `{brief.language}` files in step 3's §2 filtered file list, at most 3.
24
+ - `skf`: run `uv run {mergeCccExclusionsHelper} --clone-root "{ccc_root}" --include-ext {ext}`, with one `--include-ext` per extension. It appends a single-quoted `- '**/*.{ext}'` item for each extension no `include_patterns` entry matches (`includes_added_list`) and lists the extensions an entry already matches (`includes_covered_list`). On a file with no `include_patterns` list it adds nothing and says so in `warnings`, since a list written from scratch replaces ccc's default file types: display that `{ccc_root}/.cocoindex_code/settings.yml` has no `include_patterns` list to add the `{brief.language}` file types to, and return **degraded**. When `includes_covered_list` holds every extension, the files are excluded rather than left out of `include_patterns`: skip this repair and display which `exclude_patterns` entry covers the `{brief.language}` source files (`**/build` covers a package under `src/build/`, for example). Otherwise display "Added {includes_added_list} to include_patterns in {ccc_root}/.cocoindex_code/settings.yml so ccc indexes {brief.language} files.", run a plain `cd "{ccc_root}" && ccc index`, then run `ccc status` and check `Languages:` again.
25
+ - `user`: the settings belong to the user's project, so do not edit them. Keep the extensions that no `include_patterns` entry matches. If there are none, the files are excluded rather than left out of `include_patterns`: display which `exclude_patterns` entry covers the `{brief.language}` source files. Otherwise display that ccc did not index `{brief.language}` files, and the exact lines to add under `include_patterns` in `{ccc_root}/.cocoindex_code/settings.yml`, one single-quoted `- '**/*.{ext}'` line per extension (YAML reads an unquoted leading `*` as an alias, and ccc then fails to load the file), followed by a plain `ccc index`.
26
+
27
+ A plain `ccc index` is enough after any `settings.yml` edit; nothing needs deleting first. Do not run `ccc reset`: it deletes only the index databases and keeps `settings.yml`, so it cannot repair the settings, a `ccc index` right after it can fail and leave the project with no index, and run from a folder without its own `settings.yml` it deletes the enclosing project's index. If the source language is still missing after these repairs, return **degraded** to the caller.