bmad-module-skill-forge 2.1.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 +51 -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 +14 -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 +117 -9
  75. package/src/shared/scripts/skf-detect-docs.py +892 -4
  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 +215 -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 +17 -6
  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 +55 -18
  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 -57
  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 -89
  348. package/src/skf-setup/references/detect-and-tier.md +58 -66
  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 -645
  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,120 +1,60 @@
1
1
  ---
2
2
  nextStepFile: 'write-config.md'
3
3
  # `{mergeCccExclusionsHelper}` = first existing path in
4
- # `{mergeCccExclusionsProbeOrder}`; halt if neither exists. The script owns
5
- # config-value validation and the set-union merge into
6
- # .cocoindex_code/settings.yml — no prose fallback.
4
+ # `{mergeCccExclusionsProbeOrder}`; halt if neither exists.
7
5
  mergeCccExclusionsProbeOrder:
8
6
  - '{project-root}/_bmad/skf/shared/scripts/skf-merge-ccc-exclusions.py'
9
7
  - '{project-root}/src/shared/scripts/skf-merge-ccc-exclusions.py'
8
+ # `{emitEnvelopeHelper}` = first existing path in `{emitEnvelopeProbeOrder}`,
9
+ # for the blocked envelope a halt in this step emits under headless or quiet.
10
+ emitEnvelopeProbeOrder:
11
+ - '{project-root}/_bmad/skf/shared/scripts/skf-emit-result-envelope.py'
12
+ - '{project-root}/src/shared/scripts/skf-emit-result-envelope.py'
10
13
  ---
11
14
 
12
- <!-- Config: communicate in {communication_language}. User-visible status messages (CCC exclusion summary, indexing progress message) render in the user's language. -->
15
+ <!-- Config: communicate in {communication_language}. User-visible status messages (indexing progress message) render in the user's language. -->
13
16
 
14
- # Step 1b: CCC Index Verification
17
+ # Step 1b: CCC Index
15
18
 
16
19
  ## STEP GOAL:
17
20
 
18
- If ccc is available (`{ccc: true}` from step 1), invoke `{mergeCccExclusionsHelper}` to validate config-driven SKF exclusion patterns and merge them into `.cocoindex_code/settings.yml`, then verify the project's ccc index exists and create or refresh it if needed. Store index state and exclusion-merge results in context for step 2 to write into forge-tier.yaml and for step 4 to surface in the JSON envelope.
19
-
20
- For Quick and Forge tiers, or when ccc is unavailable, skip silently and proceed.
21
+ When ccc is available, run `{mergeCccExclusionsHelper}` once: it prepares `.cocoindex_code/settings.yml` (running `ccc init` when needed), keeps its SKF exclusion patterns current, builds or refreshes the project index when it needs it, and writes its result to `{run_dir}/ccc-exclusions.json`, where step 2 and step 4 read it.
21
22
 
22
23
  ## Rules
23
24
 
24
- - Focus only on ccc index verification, exclusion-pattern merge, and (re-)indexing
25
- - Do not display skip messages for Quick/Forge tiers
26
- - Do not fail the workflow if ccc indexing fails
27
- - The script owns exclusion-pattern validation — do not reimplement it in prose
25
+ - The script owns `ccc init`, every `settings.yml` edit, the index decision, `ccc index` and `ccc status`: run none of them yourself, and bind nothing from its output (steps 2 and 4 read the result file)
26
+ - Do not fail the workflow if settings preparation or ccc indexing fails: the result file records the failure, and the report shows it
27
+ - Display messages only when `{quiet_mode}` is false; the one exception is the envelope line a halt displays
28
+ - When `{quiet_mode}` is true, write no assistant text at all between tool calls: no status, progress or step-transition notes, however brief
29
+ - If no path in `mergeCccExclusionsProbeOrder` exists when section 2 runs (an install fault, not a settings failure), halt with phase `step 1b:helper-missing`, `path` set to its first entry, and reason `Setup cannot proceed: skf-merge-ccc-exclusions.py was not found. Reinstall SKF, then re-run /skf-setup.`
30
+ - Every halt follows the SKILL.md halt contract: when `{quiet_mode}` is true, run `uv run {emitEnvelopeHelper} emit-blocked --phase '<phase>' --reason '<reason>' --path "<path>"`, which builds the payload itself (no `--path` for a halt without one, `--stderr-from` where the halt names it, and `--customization-resolver-unavailable "<reason>"` once SKILL.md On Activation item 6 bound `{customization_resolver_unavailable}` to a reason, escaped as the halt contract says), and display its stdout line verbatim and nothing else (the reason alone if `{emitEnvelopeHelper}` resolves to no path, or the helper exits non-zero or prints no line); otherwise display the reason
28
31
 
29
32
  ## MANDATORY SEQUENCE
30
33
 
31
34
  ### 1. Check Eligibility
32
35
 
33
- Read `{ccc}` and `{ccc_skip_index}` from context.
34
-
35
- **If `{ccc}` is false:** Set `{ccc_index_result: "none", ccc_indexed_path: null, ccc_last_indexed: null, ccc_exclude_patterns: [], ccc_exclusion_warnings: [], settings_yml_written: false, settings_yml_patterns_added: 0}`. Proceed directly to section 5 (Auto-Proceed) — no output, no messaging.
36
-
37
- **If `{ccc}` is true AND `{ccc_skip_index}` is true:** Run the exclusion-merge (section 3) so settings.yml stays current, then set `{ccc_index_result: "skipped", ccc_indexed_path: null, ccc_last_indexed: null}` and proceed to section 5 (Auto-Proceed) — do not run `ccc init` or `ccc index`. The envelope's `ccc_index.status` will be `"skipped"` so pipelines that plan an out-of-band re-index can distinguish "the operator opted out" from "indexing failed".
38
-
39
- **If `{ccc}` is true AND `{ccc_skip_index}` is false:** Continue to section 2.
40
-
41
- ### 2. Check Existing Index State
42
-
43
- Consume prior CCC state from stage 1's detector output (`prior.*` context flags) — no YAML re-parse and no timestamp math here. The detector already read forge-tier.yaml and computed the freshness verdict `{ccc_index_fresh}` against `{project-root}` and the current time (same-project path match AND `"fresh"`/`"created"` status AND `last_indexed` within the staleness threshold, defaulting to 24 hours).
44
-
45
- Decide `{needs_reindex}` and `{ccc_index_result}` from `{ccc_index_fresh}`:
46
-
47
- - If `{ccc_index_fresh}` is true → index is fresh. Set `{needs_reindex: false}`, `{ccc_index_result: "fresh", ccc_indexed_path: {project-root}, ccc_last_indexed: {previous_ccc_last_indexed}}`. Exclusions still merge in section 3 (which may force a re-index).
48
- - If `{ccc_index_fresh}` is false (path mismatch, non-fresh status, stale timestamp, or any required prior CCC field null) → `{needs_reindex: true}`.
36
+ If `{ccc}` (from step 1) is false, go to section 3 with no output. Otherwise continue to section 2, with or without `--ccc-skip-index`: the skip lane still prepares settings.yml, and only the index build is skipped.
49
37
 
50
- ### 3. Merge SKF Exclusion Patterns
38
+ ### 2. Prepare the Settings and the Index
51
39
 
52
- SKF infrastructure and output directories must be excluded from the CCC index — they contain workflow instructions, build artifacts, and generated skills that pollute semantic search results with zero extraction value.
40
+ Unless `{quiet_mode}` is true, display: "**Preparing the ccc settings, then the semantic index if it needs building: a first index can take several minutes on large codebases (1000+ files). Run `ccc status` in another terminal to monitor progress.**"
53
41
 
54
- Forward `skills_output_folder` and `forge_data_folder` from `{project-root}/_bmad/skf/config.yaml` **verbatim** — the script resolves `{project-root}/...` template strings and rejects absolute paths / placeholders / glob meta-chars internally. The step does no string surgery; that work moved into the helper. Invoke via `uv run`.
42
+ Pass `{ccc_index_fresh}` (from step 1) and `{ccc_skip_index}` as `true` or `false`, and add `--defer-index` only when `{require_tier_satisfied}` (from step 1) is `false`: a run that ends `tier_failure` then builds no index that is due, while a fresh index record still carries forward. Give the call an extended timeout (or run it in the background and wait for it to finish):
55
43
 
56
44
  ```bash
57
45
  uv run {mergeCccExclusionsHelper} \
58
46
  --project-root "{project-root}" \
59
- --skills-output-folder "{skills_output_folder}" \
60
- --forge-data-folder "{forge_data_folder}"
61
- ```
62
-
63
- The script (see `src/shared/scripts/skf-merge-ccc-exclusions.py` docstring for the full schema) builds the SKF exclusion list (4 always-include hardcoded patterns + 2 conditional from validated config), applies the validation rules to reject empty / absolute / glob-meta config values with actionable warnings, and performs an idempotent set-union merge into `{project-root}/.cocoindex_code/settings.yml`. User customizations are preserved. When the file does not exist yet (first-time setup before `ccc init`) the script creates it; when nothing new needs adding the script skips the write entirely (mtime preserved).
64
-
65
- **Parse the JSON output and set context flags:**
66
-
67
- - `{settings_yml_existed}` ← `settings_yml_existed`
68
- - `{settings_yml_written}` ← `written`
69
- - `{settings_yml_patterns_added}` ← `patterns_added`
70
- - `{ccc_exclude_patterns}` ← `effective_patterns` (the script returns the final, sorted, deduplicated SKF pattern set after validation — consume verbatim; do not re-derive in prose).
71
- - `{ccc_exclusion_warnings}` ← `warnings` (a list — step 4 folds them into the envelope's warnings array)
72
-
73
- **If `{settings_yml_written}` is true** (new patterns merged into settings.yml): set `{needs_reindex: true}` — new exclusions require re-indexing for the index to reflect them. Display: "**CCC exclusions configured:** {patterns_added} SKF patterns applied to .cocoindex_code/settings.yml"
74
-
75
- **If `{settings_yml_written}` is false** (idempotent re-run, all patterns already present): display nothing (exclusions already configured). Do NOT change `{needs_reindex}` — it stays at whatever section 2 set it to.
76
-
77
- **Flow decision:**
78
-
79
- - If `{needs_reindex}` is true: proceed to section 4
80
- - If `{needs_reindex}` is false: proceed to section 5 (Auto-Proceed)
81
-
82
- ### 4. Create or Refresh CCC Index
83
-
84
- **If `{ccc_daemon}` is `"stopped"` or `"healthy"`:** the `ccc index` command auto-starts the daemon when needed.
85
-
86
- **If `{ccc_daemon}` is `"error"`:** attempt indexing anyway — errors will be caught below.
87
-
88
- Run (CWD must be `{project-root}`):
89
-
90
- ```bash
91
- ccc init
92
- ```
93
-
94
- **If init fails** (project may already be initialized): continue — this is not an error. Note: when `{settings_yml_existed}` was false and `ccc init` just created the settings.yml, the merge in section 3 ran BEFORE ccc init. The script handles "no settings.yml exists" by creating one with just the SKF exclusions, which `ccc init` will then either preserve (if it merges) or overwrite (in which case the next workflow run re-merges). Either way the SKF exclusions end up in the file by the time `ccc index` runs the second time.
95
-
96
- Before invoking `ccc index`, display: "**Building semantic index — this can take several minutes on large codebases (1000+ files). Run `ccc status` in another terminal to monitor progress.**" so the user does not assume the workflow has hung during the long-running call.
97
-
98
- Then run:
99
-
100
- ```bash
101
- ccc index
47
+ --config "{project-root}/_bmad/skf/config.yaml" \
48
+ --prior-state-from "{sidecar_path}/forge-tier.yaml" \
49
+ --index-fresh "{ccc_index_fresh}" \
50
+ --skip-index "{ccc_skip_index}" \
51
+ [--defer-index] \
52
+ --build-index \
53
+ --result-to "{run_dir}/ccc-exclusions.json"
102
54
  ```
103
55
 
104
- **Note:** `ccc index` can take several minutes on large codebases (1000+ files). Run with an extended timeout or in background mode. Use `ccc status` to verify completion — check that `Chunks` and `Files` counts are non-zero.
105
-
106
- **If succeeds:**
107
-
108
- - Run `ccc status` to get file count
109
- - Store `{ccc_index_result: "created", ccc_indexed_path: {project-root}, ccc_last_indexed: {current ISO timestamp}, ccc_file_count: {count from ccc status}}`
110
- - Display: "**CCC index created.** {ccc_file_count} files indexed for semantic discovery."
111
-
112
- **If fails:**
113
-
114
- - Store `{ccc_index_result: "failed", ccc_indexed_path: null, ccc_last_indexed: null, ccc_indexing_failed_reason: {error}}` (the failed-reason flag flows into step 4's envelope warnings)
115
- - Display: "CCC indexing failed: {error}. Extraction will use direct AST scanning — semantic pre-ranking unavailable this session."
116
- - Continue — this is not a workflow error
56
+ Go on to section 3 however the call ends: a non-zero exit, or a call the shell stopped, is no workflow error either (steps 2 and 4 report it as a failed index).
117
57
 
118
- ### 5. Auto-Proceed
58
+ ### 3. Auto-Proceed
119
59
 
120
- After ccc index verification is complete (or skipped because ccc is unavailable), display "**Proceeding to write configuration...**", then load `{nextStepFile}`, read it fully, and execute it.
60
+ Load `{nextStepFile}`, read it fully, and execute it.
@@ -1,11 +1,15 @@
1
1
  ---
2
2
  nextStepFile: 'ccc-index.md'
3
3
  # `{detectToolsHelper}` = first existing path in `{detectToolsProbeOrder}`;
4
- # halt if neither exists. This script is the source of truth for tool
5
- # detection and tier calculation — no prose-driven probes.
4
+ # halt if neither exists.
6
5
  detectToolsProbeOrder:
7
6
  - '{project-root}/_bmad/skf/shared/scripts/skf-detect-tools.py'
8
7
  - '{project-root}/src/shared/scripts/skf-detect-tools.py'
8
+ # `{emitEnvelopeHelper}` = first existing path in `{emitEnvelopeProbeOrder}`,
9
+ # for the blocked envelope a halt in this step emits under headless or quiet.
10
+ emitEnvelopeProbeOrder:
11
+ - '{project-root}/_bmad/skf/shared/scripts/skf-emit-result-envelope.py'
12
+ - '{project-root}/src/shared/scripts/skf-emit-result-envelope.py'
9
13
  ---
10
14
 
11
15
  <!-- Config: communicate in {communication_language}. The first-run preamble below is user-visible — render it in the user's language. -->
@@ -14,100 +18,88 @@ detectToolsProbeOrder:
14
18
 
15
19
  ## STEP GOAL:
16
20
 
17
- Verify availability of the four forge tools (ast-grep, gh, qmd, ccc), read any existing configuration for re-run comparison, check for tier override, and calculate the capability tier — all via `{detectToolsHelper}` so the deterministic work is done once, by a tested script, never by the LLM.
21
+ Through `{detectToolsHelper}`, verify the four forge tools (ast-grep, gh, qmd, ccc), each at its minimum version, compare them with the previous run's configuration, and calculate the capability tier. Then, on an interactive run, tell the user what setup is about to write before step 1b or step 2 writes anything.
18
22
 
19
23
  ## Rules
20
24
 
21
- - Focus only on tool detection and tier calculation — do not write any files (Step 02)
22
- - Never reimplement tool probes or the tier rules in prose — the script is authoritative
23
- - Tool command failures are not errors — they indicate unavailability (the script swallows them)
25
+ - Focus only on tool detection and tier calculation: write nothing but this run's folder and the detector's output and stderr in it (step 2 writes the configuration)
26
+ - Never reimplement tool probes or the tier rules in prose: the script is authoritative
27
+ - Display messages only when `{quiet_mode}` is false; the one exception is the envelope line a halt displays
28
+ - When `{quiet_mode}` is true, write no assistant text at all between tool calls: no status, progress or step-transition notes, however brief
29
+ - If no path in `detectToolsProbeOrder` exists, halt with phase `step 1:helper-missing`, `path` set to its first entry, and reason `Setup cannot proceed: skf-detect-tools.py was not found. Reinstall SKF, then re-run /skf-setup.`
30
+ - Every halt follows the SKILL.md halt contract: when `{quiet_mode}` is true, run `uv run {emitEnvelopeHelper} emit-blocked --phase '<phase>' --reason '<reason>' --path "<path>"`, which builds the payload itself (no `--path` for a halt without one, `--stderr-from` where the halt names it, and `--customization-resolver-unavailable "<reason>"` once SKILL.md On Activation item 6 bound `{customization_resolver_unavailable}` to a reason, escaped as the halt contract says), and display its stdout line verbatim and nothing else (the reason alone if `{emitEnvelopeHelper}` resolves to no path, or the helper exits non-zero or prints no line); otherwise display the reason
24
31
 
25
32
  ## MANDATORY SEQUENCE
26
33
 
27
- ### 1. Check for Existing Configuration (Re-run Detection)
34
+ ### 1. Run Detection Helper
28
35
 
29
- Prior state lives in two files; the detector helper (§2) reads forge-tier.yaml itself when invoked with `--prior-state-from`, so this section only handles preferences.yaml directly and the first-run preamble.
36
+ Create this run's folder:
30
37
 
31
- **Read existing preferences.yaml** at `{project-root}/_bmad/_memory/forger-sidecar/preferences.yaml`:
38
+ ```bash
39
+ mkdir -p "{project-root}/_bmad-output/.skf-run" && mktemp -d "{project-root}/_bmad-output/.skf-run/skf-setup-XXXXXXXX"
40
+ ```
32
41
 
33
- - If exists: check for `tier_override` value
34
- - If not found: set `{tier_override}` to null
42
+ Bind `{run_dir}` ← the path it prints. If the folder cannot be created, halt with phase `step 1:run-folder`, `path` `{project-root}/_bmad-output/.skf-run`, and reason `Setup cannot proceed: the run folder could not be created: <message>`, where `<message>` is the command's first stderr line. With no run folder to hold that stderr, a quiet run repeats the command with its stderr piped to the emitter, which fills `<message>`; a repeat that succeeds removes the folder it made, and its reason then ends `(no error message)`:
35
43
 
36
- **First-run preamble** — when the prior-state read (§2 below, `prior.previous_tier`) returns null AND `{headless_mode}` is `false`, display this preamble before continuing so the user knows what is about to happen and can abort cleanly with Esc / Ctrl+C before any writes. (When `{headless_mode}` is true, skip the preamble entirely — pipelines never need it.)
44
+ ```bash
45
+ { mkdir -p "{project-root}/_bmad-output/.skf-run" && rmdir "$(mktemp -d "{project-root}/_bmad-output/.skf-run/skf-setup-XXXXXXXX")"; } 2>&1 >/dev/null | uv run {emitEnvelopeHelper} emit-blocked --phase "step 1:run-folder" --path "{project-root}/_bmad-output/.skf-run" --reason "Setup cannot proceed: the run folder could not be created: <message>" --stderr-from - [--customization-resolver-unavailable "{customization_resolver_unavailable}"]
46
+ ```
37
47
 
38
- "**About to set up the forge.** This workflow will:
48
+ In each `emit-blocked` call of this step, keep the bracketed `--customization-resolver-unavailable` only when On Activation item 6 bound `{customization_resolver_unavailable}` to a reason, escaped as the halt contract says; otherwise leave it out.
39
49
 
40
- - Detect available tools (ast-grep, gh, qmd, ccc) — read-only probes only
41
- - Write `{project-root}/_bmad/_memory/forger-sidecar/forge-tier.yaml` (capability tier + tool state)
42
- - Write `{project-root}/_bmad/_memory/forger-sidecar/preferences.yaml` (first-run defaults)
43
- - Create `{forge_data_folder}/` if missing
44
- - When ccc is available: augment `{project-root}/.cocoindex_code/settings.yml` with SKF exclusion patterns, then create or refresh the project ccc index
50
+ Then run the detector into the folder:
45
51
 
46
- **About tiers:** SKF picks one of four tiers (Quick / Forge / Forge+ / Deep) based on which tools are installed. **All four are fully usable** — higher tiers add power, they don't fix gaps. If you're new and only have a base Python install, Quick tier is the right starting point and the report at the end will show you exactly which tools to install if you want to climb later.
52
+ ```bash
53
+ uv run {detectToolsHelper} --project-root "{project-root}" \
54
+ --prior-state-from "{sidecar_path}/forge-tier.yaml" \
55
+ [--tier-override="{tier_override}"] [--require-tier="{require_tier}"] \
56
+ > "{run_dir}/detect-tools.json" 2> "{run_dir}/detect-tools.err" && cat "{run_dir}/detect-tools.json"
57
+ ```
47
58
 
48
- Press Esc or Ctrl+C now if this isn't the right project — no files have been written yet."
59
+ Pass `--tier-override` only when `{tier_override}` (bound at activation from `preferences.yaml`) is non-null, and `--require-tier` only when `{require_tier}` is non-null, with the value exactly as activation bound it, even when it names no tier: the script rejects such a value, and the halt below then names the valid tiers.
49
60
 
50
- **Re-run notice** — when the prior-state read (§2 below, `prior.previous_tier`) returns a non-null value AND `{headless_mode}` is `false`, display this notice instead of the first-run preamble, before continuing, so a user who re-ran in the wrong/sibling repo can abort before any config rewrite or re-index. (When `{headless_mode}` is true, skip it — pipelines re-run intentionally.)
61
+ Output is one JSON document on stdout; `DETECT_OUTPUT_SCHEMA` in the helper's docstring documents it.
51
62
 
52
- "**Forge already set up here:** {previous_tier} tier, detected {previous_detection_date}. Re-running re-probes the tools and refreshes config/index in this project. To refresh the tier without paying the ccc re-index cost, re-run with `--ccc-skip-index`. Press Esc or Ctrl+C now if this isn't the project you meant — nothing has been rewritten yet."
63
+ **If the script exits non-zero or prints no JSON:** halt before section 2 with phase `step 1:detect-tools`, `path` `{project-root}`, and reason `Setup cannot proceed: tool detection failed: <message>`, where `<message>` is the diagnostic in `{run_dir}/detect-tools.err`: an interactive run reads that file and shows the `message` of its JSON error, else its first line. Under `{quiet_mode}` the blocked envelope is the only line displayed, and the emitter reads `<message>` from that file:
53
64
 
54
- ### 2. Run Detection Helper
65
+ ```bash
66
+ uv run {emitEnvelopeHelper} emit-blocked --phase "step 1:detect-tools" --path "{project-root}" \
67
+ --reason "Setup cannot proceed: tool detection failed: <message>" --stderr-from "{run_dir}/detect-tools.err" \
68
+ [--customization-resolver-unavailable "{customization_resolver_unavailable}"]
69
+ ```
55
70
 
56
- Build the Bash invocation: `uv run {detectToolsHelper} --project-root "{project-root}" --prior-state-from "{project-root}/_bmad/_memory/forger-sidecar/forge-tier.yaml"`. If `{tier_override}` is non-null, append `--tier-override "{tier_override}"`. If `{require_tier}` is non-null, append `--require-tier "{require_tier}"`. Then execute. (`--project-root` lets the script compute the CCC-index freshness verdict — `prior.ccc_index_fresh` — so step 1b branches on a boolean instead of doing timestamp math.)
71
+ ### 2. Parse Output and Set Context Flags
57
72
 
58
- The script (see `src/shared/scripts/skf-detect-tools.py` docstring for the full `DETECT_OUTPUT_SCHEMA`) probes ast-grep / gh / qmd / ccc concurrently with two-step verification for qmd and ccc (binary-identity check + daemon-health check, including the `CocoIndex Code` identity-marker substring check that rejects PATH-shadowing aliases). It applies the 4-rule tier table, performs the tier-override sanity check (override is honored but flagged unsafe when underlying tools are missing), and evaluates `--require-tier` using a tool-prerequisite check (Deep does not subsume Forge+ — Deep does not require ccc). Output is one JSON document on stdout.
73
+ Steps 2 and 4 read the staged `detect-tools.json` themselves. Bind only what the next steps branch on (field paths are relative to the script's top-level object):
59
74
 
60
- ### 3. Parse Output and Set Context Flags
75
+ - `{ccc}` ← `tools.ccc.available`
76
+ - `{calculated_tier}` ← `tier.calculated`, the tier downstream steps act on
77
+ - `{require_tier_satisfied}` ← `require_tier.satisfied` (`true | false | null`; null when `--require-tier` was not set) and `{require_tier_failure_missing_tools}` ← `require_tier.missing_tools` (a list)
78
+ - `{previous_tier}` ← `prior.previous_tier` and `{previous_detection_date}` ← `prior.previous_detection_date` (both null on a first run)
79
+ - `{ccc_index_fresh}` ← `prior.ccc_index_fresh` (boolean; step 1b forwards it as `--index-fresh`)
61
80
 
62
- From the JSON, set these context flags. Field paths are relative to the script's top-level object.
81
+ A tier tool below its minimum version binds `false` here, like a missing one: it counts toward no tier, and step 4 names it with its upgrade from the staged output.
63
82
 
64
- From `tools`:
83
+ ### 3. Show the First-Run Preamble or the Re-run Notice (skip when `{quiet_mode}` is true)
65
84
 
66
- - `{ast_grep}` ← `tools.ast_grep.available`
67
- - `{ast_grep_version}` ← `tools.ast_grep.version`
68
- - `{gh_cli}` ← `tools.gh_cli.available`
69
- - `{gh_cli_version}` ← `tools.gh_cli.version`
70
- - `{qmd}` ← `tools.qmd.available`
71
- - `{qmd_status}` ← `tools.qmd.status` (`"absent" | "daemon_stopped" | "healthy"` — drives the climb-hint distinction in step 4)
72
- - `{qmd_version}` ← `tools.qmd.version`
73
- - `{ccc}` ← `tools.ccc.available`
74
- - `{ccc_daemon}` ← `tools.ccc.daemon` (`"healthy" | "stopped" | "error" | null`)
75
- - `{ccc_version}` ← `tools.ccc.version`
76
- - `{security_scan}` ← `tools.security_scan.available` (informational only — never affects tier)
85
+ Now that section 2 has bound `{previous_tier}` and `{previous_detection_date}`, and before step 1b or step 2 writes anything, display one of these:
77
86
 
78
- From `tier`:
87
+ **First-run preamble:** when `{previous_tier}` is null:
79
88
 
80
- - `{calculated_tier}` ← `tier.calculated` — the tier downstream steps act on
81
- - `{detected_tier}` ← `tier.detected` — what would have been chosen without override
82
- - `{tier_override_active}` ← `tier.override_applied`
83
- - `{tier_override_invalid}` ← `tier.override_invalid`
84
- - `{tier_override_invalid_value}` ← `tier.override_invalid_value`
85
- - `{tier_override_invalid_suggestion}` ← `tier.override_invalid_suggestion` (closest valid tier name from a fuzzy match — `null` when no candidate cleared the cutoff or when override is valid; consumed by step 4's invalid-override note as a "did you mean ...?" hint)
86
- - `{tier_override_unsafe}` ← `tier.override_unsafe`
87
- - `{tier_override_unsafe_missing}` ← `tier.override_unsafe_missing` (a list — step 4 joins with `", "` for display)
89
+ "**About to set up the forge.** Setup has probed the available tools (ast-grep, gh, qmd and ccc, plus git and uv), read-only, and keeps their result in the scratch folder `{run_dir}` until it finishes. It goes on now to:
88
90
 
89
- From `require_tier`:
90
-
91
- - `{require_tier_satisfied}` ← `require_tier.satisfied` (`true | false | null`; null when `--require-tier` was not set)
92
- - `{require_tier_failure_missing_tools}` ← `require_tier.missing_tools` (a list)
91
+ - Write `{sidecar_path}/forge-tier.yaml` (capability tier + tool state)
92
+ - Create `{forge_data_folder}/` if missing
93
+ - When ccc is available: prepare `{project-root}/.cocoindex_code/settings.yml` (run `ccc init` if it is missing, which in a git checkout also adds `/.cocoindex_code/` to `.gitignore`; merge the SKF exclusion patterns and remove ones a previous folder config left behind), then create or refresh the project ccc index
93
94
 
94
- From `prior` (populated by `--prior-state-from`; all fields null/empty on first run):
95
+ **About tiers:** SKF picks one of four tiers (Quick / Forge / Forge+ / Deep) based on which tools are installed, each at its minimum version or newer. **All four are fully usable**: higher tiers add power, they don't fix gaps. If you're new and only have a base Python install, Quick tier is the right starting point and the report at the end will show you exactly which tools to install or upgrade if you want to climb later."
95
96
 
96
- - `{previous_tier}` ← `prior.previous_tier`
97
- - `{previous_detection_date}` ← `prior.previous_detection_date`
98
- - `{previous_tools}` ← `prior.previous_tools`
99
- - `{previous_ccc_index_status}` ← `prior.previous_ccc_index_status`
100
- - `{previous_ccc_indexed_path}` ← `prior.previous_ccc_indexed_path`
101
- - `{previous_ccc_last_indexed}` ← `prior.previous_ccc_last_indexed`
102
- - `{previous_ccc_staleness_threshold_hours}` ← `prior.previous_ccc_staleness_threshold_hours`
103
- - `{ccc_index_fresh}` ← `prior.ccc_index_fresh` (boolean; the script's deterministic freshness verdict — prior index covers this project AND status was fresh/created AND `last_indexed` is within the staleness threshold of now. Step 1b branches on this directly instead of doing timestamp math.)
97
+ **Re-run notice:** when `{previous_tier}` is non-null:
104
98
 
105
- From `deltas` (computed by the script from current tools + prior; eliminates LLM-side set arithmetic in the report banner):
99
+ "**Forge already set up here:** {previous_tier} tier, detected {previous_detection_date}. The tools were just re-probed, and setup now refreshes this project's config and ccc index. Next time, to refresh only the tier without paying the ccc re-index cost, run it with `--ccc-skip-index`."
106
100
 
107
- - `{tools_added}` ← `deltas.tools_added` (the list)
108
- - `{tools_removed}` ← `deltas.tools_removed` (the list)
109
- - `{tier_changed}` ← `deltas.tier_changed` (boolean)
101
+ When `{require_tier_satisfied}` is `false`, end the one you display with: "`--require-tier {require_tier}` is not met: this run writes the detected tier but builds no ccc index and runs no registry hygiene."
110
102
 
111
103
  ### 4. Auto-Proceed
112
104
 
113
- After context flags are populated, display "**Proceeding to CCC index check...**", then load `{nextStepFile}`, read it fully, and execute it.
105
+ Load `{nextStepFile}`, read it fully, and execute it.
@@ -18,6 +18,8 @@ Chain to the shared workflow self-improvement health check at `{nextStepFile}`.
18
18
  - No user-facing reports, file writes, or result contracts in this step — those belong in step 4
19
19
  - Delegate directly to `{nextStepFile}` with no additional commentary
20
20
  - Do not attempt any other action between loading this step and executing `{nextStepFile}`
21
+ - `{quiet_mode}` reaches `{nextStepFile}` as activation set it: skf-setup is the only workflow that sets it, and when it is true the shared health check displays nothing of its own, queues any findings locally, and displays step 4's `{setup_envelope_line}` verbatim last, as the final message of a standalone run; when `{pipeline_mode}` is true, control then returns to the forger, which keeps chaining
22
+ - When `{quiet_mode}` is true, write no assistant text at all between tool calls: no status, progress or step-transition notes, however brief
21
23
 
22
24
  ## MANDATORY SEQUENCE
23
25
 
@@ -0,0 +1,14 @@
1
+ # skf-setup Invocation Contract
2
+
3
+ The flags, gate, outputs, headless contract and failure modes of `skf-setup`, for headless callers and pipeline integrators. No run loads this file: SKILL.md's On Activation and the step files hold everything a run does.
4
+
5
+ ## Invocation Contract
6
+
7
+ | Aspect | Detail |
8
+ |--------|--------|
9
+ | **Inputs** | (none) |
10
+ | **Flags** | `--headless` / `-H` (skip prompts, auto-resolve gates to defaults); `--quiet` (an alias of `--headless`; its step 3 orphan default is recorded as `quiet-default`); `--require-tier=<Quick\|Forge\|Forge+\|Deep>` or `--require-tier <tier>` (halt with failure if calculated tier does not satisfy the requirement; any other value halts the run `blocked`, see Failure modes); `--orphan-action=<keep\|remove>` (resolve the orphan-removal gate non-interactively, even outside `--headless`; any other value halts at activation); `--ccc-skip-index` (skip building the CCC index: settings.yml is still prepared and its SKF exclusions kept current, and the envelope's `ccc_index.status` becomes `"skipped"`; the fast re-probe lane for an expert re-running only to refresh the detected tier without paying the full ccc re-index cost) |
11
+ | **Gates** | One optional: orphaned QMD collection removal (step 3, Deep tier only; default: Keep, or whatever `--orphan-action` set; resolves without prompting under `--headless` or `--quiet`). Only a collection with a forge suffix that the registry does not list and whose QMD path lies inside this project is offered: another project's collections never are |
12
+ | **Outputs** | `{sidecar_path}/forge-tier.yaml` and `{forge_data_folder}/` (setup never writes `preferences.yaml`: the installer creates it, and setup reads it when it is there); when ccc is available, `.cocoindex_code/settings.yml` (created by `ccc init` when missing; SKF exclusion patterns merged and stale ones removed), a `/.cocoindex_code/` line in `.gitignore` when `ccc init` adds one, and the project ccc index; for the run itself, a scratch folder under `{project-root}/_bmad-output/.skf-run/` holding the helpers' outputs, which step 4 deletes (a halt that names a phase leaves it in place) |
13
+ | **Headless** | All gates auto-resolve with their default action under `--headless` or its alias `--quiet`, under `headless_mode: true` in `{sidecar_path}/preferences.yaml` (known once activation has loaded it, so the halts before that emit an envelope only under a flag or in a pipeline), and in a forger pipeline. Under `--headless`, `--quiet` or `headless_mode: true`, a standalone run's final message, and so everything `claude -p` prints, is exactly one line: the single-line `SKF_SETUP_RESULT_JSON: {…}` envelope from step 4 (displayed once the health check has finished, or at the tier-miss halt), or a blocked envelope from a halt, or the bare halt reason when no envelope helper can run (see Failure modes). Setup displays no FORGE STATUS banner or health-check output, and no halt diagnostic beyond that one line; the health check still runs and saves any findings to the local improvement queue. Inside a forger pipeline (`{pipeline_mode}` true), setup displays the same line and returns control to the forger. Branch on the envelope's top-level `status` field: `success`, `tier_failure` (require-tier miss), or `blocked` (any pre-report halt, whose `error.phase` names the cause). `skf-emit-result-envelope.py` derives `status` from the run's staged outputs, so pipelines never compose it from `require_tier_satisfied` + `error`. Schema: `shared/scripts/schemas/skf-setup-result-envelope.v1.json`. |
14
+ | **Failure modes** | `--require-tier` not satisfied → status `tier_failure`, the envelope sets `"require_tier_satisfied": false`, and the workflow halts before step 5 (interactive runs also print a "REQUIRED TIER NOT MET" block). Such a run fails fast: it builds no ccc index that is due (`ccc_index.status` `"skipped"`, while a fresh index record still carries forward) and runs no registry hygiene, so it removes no QMD collection, even under `--orphan-action=remove`; it still writes `forge-tier.yaml` with the detected tier. A `--require-tier` value that is not exactly one of the four tiers is no miss: the detector rejects it, and the run ends `blocked` at `step 1:detect-tools` with a reason that names the valid tiers (with a did-you-mean hint for a wrong-case tier). A write failure (forge-tier.yaml or the forge data folder could not be written) halts step 2 with a `blocked` envelope whose `error.phase` (`step 2:write-tools` or `step 2:forge-data-dir`) and `error` name the path and reason. The other halts (uv missing, config missing, malformed or naming no usable `sidecar_path`, an `--orphan-action` other than `keep` or `remove`, a run folder that cannot be created, a helper that no probe path resolves, a failed tool detection) end the same way under `--headless` or `--quiet`: `error.phase` names the halt and `error.reason` carries the diagnostic. The exception is a run where the envelope helper itself cannot run (SKF's scripts are not installed in the project, as in a directory that is not an SKF project, or an On Activation halt on a machine where none of `uv`, `python3`, `python` and `py -3` can run it): its one line is the bare halt reason with no envelope, and a pipeline treats a missing envelope as a failure. |