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
@@ -16,9 +16,10 @@ To assemble the best-effort SKILL.md document, context-snippet.md in Vercel-alig
16
16
 
17
17
  ## Rules
18
18
 
19
- - Focus only on assembling the three output documents — do not write files to disk (that's step 6)
19
+ - Focus only on assembling the three output documents: do not write files to disk (step 5 writes them)
20
20
  - Follow template structure exactly from {skillTemplateData}
21
21
  - Mark any sections with insufficient data as best-effort
22
+ - A HARD HALT prints, after its envelope, this step's `halt` event when `{headless_mode}` is true. Under `--batch` it ends only this target: then return to `references/batch-mode.md` §3, even when the halt reads as the end of the run (`references/halt-contract.md`).
22
23
 
23
24
  ## Steps
24
25
 
@@ -34,7 +35,7 @@ Load {skillTemplateData} to understand:
34
35
  Populate the SKILL.md section structure from `{skillTemplateData}` § "SKILL.md Section Structure" (the frontmatter skeleton and the Required/Optional section list live there) using extraction_inventory. The rules below are the deltas the template does not encode:
35
36
 
36
37
  **Frontmatter rules (agentskills.io compliance):**
37
- - `name`: lowercase alphanumeric + hyphens only, must match the skill output directory name. Prefer gerund form (`processing-pdfs`) for clarity.
38
+ - `name` is `{repo_name}`: step 5 writes that folder and validates the name against it.
38
39
  - `description`: non-empty, max 1024 chars, optimized for agent discovery. Use third-person voice ("Processes..." not "I can..." / "You can...") so it reads correctly in the agent's skill index.
39
40
  - No other frontmatter fields — only `name` and `description` for community skills
40
41
 
@@ -42,48 +43,52 @@ Populate the SKILL.md section structure from `{skillTemplateData}` § "SKILL.md
42
43
  - **Description:** From `{overrides.description}` if set (subject to the same length/voice checks as extracted descriptions); otherwise from extraction_inventory.description (README-derived)
43
44
  - **Key Exports:** From `{overrides.exports}` if set (comma-separated names parsed and trimmed; empty items skipped); otherwise from extraction_inventory.exports — list each with name, type, brief description
44
45
 
45
- **Scripts & Assets Note** (add as an optional section if source contains `scripts/`, `bin/`, `assets/`, `templates/`, or `schemas/` directories): "This package may include scripts and assets. Run create-skill for full extraction with provenance tracking."
46
+ **Skills module** (`repo_shape: skills-module`): Unless `{overrides.exports}` is set, Key Exports lists the skills first, each with its description, then the menu codes, each with its description, display name and the skill it runs, in the inventory's order. Usage Patterns gives one entry per `module-help.csv` usage pattern in the inventory; with no `module-help.csv`, it comes from the README as for a library.
47
+
48
+ **Scripts & Assets Note** (add as an optional section when step 3's `{run_dir}/sniff.json` lists a `scripts/`, `bin/`, `assets/`, `templates/` or `schemas/` folder: its `asset_dir_count` is above 0): "This package may include scripts and assets. Run create-skill for full extraction with provenance tracking."
46
49
 
47
50
  **If confidence is low** — include a note: "This skill was generated with limited source data. Consider running create-skill for a more thorough compilation."
48
51
 
49
52
  ### 3. Generate Context Snippet
50
53
 
51
- **If `{overrides.skip_snippet}` is true** — skip generation and note in the §5 preview: "context-snippet.md skipped per `--skip-snippet` override." Step-05 §2 will skip the corresponding write; step 5 §5 advisory snippet validation will report a "skipped" entry.
54
+ **If `{overrides.skip_snippet}` is true**, skip generation and note in the §5 preview: "context-snippet.md skipped per `--skip-snippet` override."
52
55
 
53
56
  Otherwise, produce context-snippet.md in the Vercel-aligned indexed format from `{skillTemplateData}` § "context-snippet.md Format" (~80-120 tokens).
54
57
 
55
- The snippet anchors point to the QS template's actual headings — `#usage-patterns` (Usage Patterns) and `#key-exports` (Key Exports). The QS template has no `## Quick Start` / `## Key Types` headings (those are Deep-tier sections), so the Deep-tier anchors `#quick-start` / `#key-types` would dangle. If the assembled SKILL.md is missing the referenced heading, omit that line rather than emit a dangling anchor.
58
+ Its `{version}` is the version §4 gives `metadata.json`, which names the version folder: `{target_version}` when step 1 parsed one from the target, else the first `version` set in step 3's extraction files (`{run_dir}/extract.json` first), else `1.0.0`.
59
+
60
+ If the assembled SKILL.md lacks a heading a snippet line anchors to, omit that line.
56
61
 
57
- **If fewer than 5 exports:** Use all available exports.
58
62
  **If no exports:** Omit the api line.
59
63
  **If no gotchas known:** Omit the gotchas line.
64
+ **If `repo_shape` is `skills-module`:** the api line names up to five skills, without `()`, and the key-types summary lists the menu codes when there are any.
60
65
 
61
66
  ### 4. Generate Metadata JSON
62
67
 
63
- Run the shared renderer against the assembled state. The helper applies the constants, echoes input-derived fields, computes export counts and the ISO 8601 UTC timestamp, and emits the canonical envelope per `{skillTemplateData}` § "metadata.json Format".
64
-
65
- **Resolve `{quickMetadataRenderer}`** from `{quickMetadataRendererProbeOrder}`; first existing path wins. If no candidate exists, fall back to in-prompt rendering of the canonical envelope per `{skillTemplateData}` § "metadata.json Format".
66
-
67
- **Probe `tool_versions.skf` first** (the helper expects it as input — the filesystem walk stays here because the helper does no I/O):
68
+ Run the shared renderer. It applies the constants, takes the export list, the dependencies and the manifest's version from step 3's extraction files, probes the installed SKF's version for `tool_versions.skf`, computes export counts and the ISO 8601 UTC timestamp, and writes the canonical envelope (it does not read the template).
68
69
 
69
- 1. Read `{project-root}/_bmad/skf/package.json` → take `version`
70
- 2. If absent, read `{project-root}/_bmad/skf/VERSION`
71
- 3. If absent, set to `"unknown"`
70
+ **Resolve `{quickMetadataRenderer}`** from `{quickMetadataRendererProbeOrder}`; first existing path wins. If no candidate exists, fall back to in-prompt rendering of the canonical envelope per `{skillTemplateData}` § "metadata.json Format", and write it to `{run_dir}/metadata.json`.
72
71
 
73
- Build the input payload from the extraction inventory + step 1 resolution + the probed `tool_versions.skf` and pipe it to the renderer:
72
+ Stage the fields this step and step 1 decide through a quoted heredoc, so a description holding an apostrophe, a quote or a `$` reaches the file as written, then run the renderer:
74
73
 
75
74
  ```bash
76
- echo '{"name":"<name>","version":"<v>","description":"<desc>","language":"<lang>","source_repo":"<url>","source_root":"<path or empty>","source_commit":"<source_ref or empty>","source_package":"<package or name>","exports":[{"name":"...","type":"..."}],"dependencies":["..."],"compatibility":"<semver-range or empty>","language_hint":<hint or null>,"scope_hint":<hint or null>,"skf_version":"<probed>"}' \
77
- | python3 {quickMetadataRenderer}
75
+ cat > "{run_dir}/metadata-input.json" <<'SKF_JSON'
76
+ {"name": "{repo_name}", "description": "<the SKILL.md frontmatter description>", "version": <"{target_version}" or null>, "language": "{language}", "source_repo": "{resolved_url}", "source_root": "<path or empty>", "source_commit": "<source_ref or empty>", "source_package": "<package name or empty>", "compatibility": "<semver-range or empty>", "language_hint": <"{language_hint}" or null>, "scope_hint": <"{scope_hint}" or null>, "exports": <the --exports names as a JSON list, or null>}
77
+ SKF_JSON
78
+ uv run {quickMetadataRenderer} --input "{run_dir}/metadata-input.json" --extraction "{run_dir}/extract.json" --skf-root "{project-root}/_bmad/skf" --output "{run_dir}/metadata.json"
78
79
  ```
79
80
 
80
- The renderer emits the rendered metadata.json on stdout. Capture the output as `metadata` for the §5 preview and step 5 §2's deliverable write.
81
+ Write each value as JSON: a string in double quotes with any `"` or `\` escaped, and `null` where the line says so. `version` is the version step 1 parsed from the target, else `null`, which takes the manifest's version (else `1.0.0`); `exports` is `{overrides.exports}` when set, else `null`, which takes the extraction's exports; an empty `source_package` takes the manifest's package name. Pass one `--extraction` per file step 3 wrote, the parent first: `{run_dir}/extract.json`, then each `{run_dir}/extract-module-<n>.json` of a multi-module build in `<n>` order and `{run_dir}/extract-added.json` when §3 staged it. Do not type the export list or the dependencies: the renderer reads them from those files.
82
+
83
+ The renderer writes `{run_dir}/metadata.json` and prints it on stdout. Read it as `metadata` for the §5 preview; step 5 §2 installs that file.
84
+
85
+ If the renderer exits non-zero, its error line names the file or the field at fault: fix that file once (stage `metadata-input.json` again with the missing field, or stage an empty extraction file as quick-extract §3's empty envelope) and run the command again. If it fails a second time, render the envelope in-prompt as the no-candidate fallback above does.
81
86
 
82
87
  ### 5. Present Compiled Output for Review
83
88
 
84
89
  **If `{headless_mode}` is true** — skip the inline preview (no human reviewer reads it) and emit a one-line summary instead:
85
90
 
86
- "Compiled: SKILL.md ({section_count} sections, {export_count} exports), context-snippet.md (~{snippet_token_count} tokens), metadata.json (version {version}, confidence {confidence}). Auto-approving [C]."
91
+ "Compiled: SKILL.md ({section_count} sections, {export_count} exports), context-snippet.md (~{snippet_token_count} tokens), metadata.json (version {metadata.version}, confidence {confidence}). Auto-approving [C]."
87
92
 
88
93
  Then proceed directly to §6 — the GATE default action takes over.
89
94
 
@@ -105,16 +110,11 @@ Then proceed directly to §6 — the GATE default action takes over.
105
110
 
106
111
  ---
107
112
 
108
- **metadata.json:**
109
-
110
- {Display the JSON}
113
+ **metadata.json:** version {metadata.version}, confidence tier {metadata.confidence_tier}, {metadata.stats.exports_documented} exports documented (step 5 writes the full file)
111
114
 
112
115
  ---
113
116
 
114
- **Extraction confidence:** {confidence}
115
- **Exports documented:** {count}
116
-
117
- Review the output above, then choose: [C] continue to validation, [E] edit the description, [S] adjust scope and re-extract, or [Q] quit without writing."
117
+ **Extraction confidence:** {confidence}"
118
118
 
119
119
  ### 6. Present MENU OPTIONS
120
120
 
@@ -123,14 +123,13 @@ Display: **Select:** [C] Continue to Validation · [E] Edit description · [S] A
123
123
  #### Menu Handling Logic:
124
124
 
125
125
  - **IF C** — Load, read entire file, then execute {nextStepFile}.
126
- - **IF E** — Ask the user for a replacement description ("New description (1–1024 chars):"). Update SKILL.md frontmatter `description` and `metadata.json.description` in the in-memory compiled output, then re-render the §5 preview and redisplay this menu. Do not re-run extraction.
127
- - **IF S** — Ask the user for an adjusted `scope_hint` ("New scope (e.g. `src/server/`, `packages/core/`):") and optionally a `language_hint`. Update the extraction context with the new hints, then load `quick-extract.md` to re-extract. The new extraction returns to §1 of this step on completion. Discards the prior compiled output.
128
- - **IF Q** — HARD HALT with **exit code 6 (user-cancelled)** per the exit-code map in `references/halt-contract.md`: "Compilation cancelled. No files written." Before exiting, emit the error result contract per `references/halt-contract.md` (`phase: "compile"`, `error.code: "user-cancelled"`, `skill_package: null`). Do not proceed to validation; do not write any artifacts.
126
+ - **IF E**: Ask the user for a replacement description ("New description (1–1024 chars):"). Update SKILL.md frontmatter `description` in the compiled output, stage `{run_dir}/metadata-input.json` again with the new description and run §4's renderer command again, so `{run_dir}/metadata.json` carries it, then re-render the §5 preview and redisplay this menu. Do not edit `metadata.json` by hand, and do not re-run extraction.
127
+ - **IF S**: Ask the user for an adjusted `scope_hint` ("New scope (e.g. `src/server/`, `packages/core/`):") and optionally a `language_hint`. A non-empty new language hint sets `language` to it, `language_resolution` to `hint` and `detected_languages` to `[]`, as step 1 §4 does for a hint. Update the extraction context with the new hints, then load `quick-extract.md` to re-extract. The new extraction returns to §1 of this step on completion. Discards the prior compiled output.
128
+ - **IF Q**: HARD HALT with **exit code 6 (user-cancelled)**: "Compilation cancelled. No files written." Stage `{"phase": "compile", "halt_reason": "user-cancelled", "reason": "Compilation cancelled. No files written.", "skill_package": null}` as `{run_dir}/halt.json` and run `uv run {emitEnvelopeHelper} emit-halt --workflow skf-quick-skill --run-dir "{run_dir}" --target stderr < "{run_dir}/halt.json"` (`references/halt-contract.md`). Do not proceed to validation; do not write any artifacts.
129
129
  - **IF Any other** — Help the user adjust the compiled output (treated as a free-form revision request), then redisplay the menu.
130
130
 
131
131
  #### Gate:
132
132
 
133
133
  - Halt and wait for user input after presenting the compiled output; only [C] (or a headless auto-approve) chains to `{nextStepFile}` for validation.
134
- - **GATE [default: C]** — If `{headless_mode}`: auto-proceed with [C] Continue, log: "headless: auto-approve compiled output"
135
- - [E] re-renders the preview without re-running extraction; [S] discards the compiled output and re-runs step 3 with new hints.
134
+ - **GATE [default: C]**: if `{headless_mode}`, auto-proceed with [C] Continue, log "headless: auto-approve compiled output", record the decision (stage `{"gate": "compile.review", "default_action": "C", "taken_action": "C", "reason": "headless: auto-approved the compiled output"}` as `{run_dir}/decision.json` and run `uv run {emitEnvelopeHelper} record --workflow skf-quick-skill --run-dir "{run_dir}" --decision < "{run_dir}/decision.json"`), and print this step's `done` event and step 5's `start` event (`references/halt-contract.md`) before loading `{nextStepFile}`.
136
135
 
@@ -6,67 +6,17 @@ nextStepFile: 'quick-extract.md'
6
6
 
7
7
  # Step 2: Ecosystem Check
8
8
 
9
- ## STEP GOAL:
10
-
11
- To query the agentskills.io ecosystem for an existing official skill matching the resolved target, preventing unnecessary duplication. This is an advisory gate — it never blocks the workflow on failure.
12
-
13
9
  ## Rules
14
10
 
15
- - 5-second timeout on ecosystem queries; tool unavailability is a silent skip, not an error
16
- - Do not begin extraction or compilation
11
+ - A HARD HALT prints, after its envelope, this step's `halt` event when `{headless_mode}` is true. Under `--batch` it ends only this target: then return to `references/batch-mode.md` §3, even when the halt reads as the end of the run (`references/halt-contract.md`).
17
12
 
18
13
  ## Steps
19
14
 
20
- ### 1. Query Ecosystem
21
-
22
- Search for an existing official skill matching `{repo_name}` in the agentskills.io ecosystem.
23
-
24
- **Query methods (try in order):**
25
- 1. Search agentskills.io registry for `{repo_name}`
26
- 2. Web search: `"agentskills.io" "{repo_name}" skill`
27
-
28
- **Apply 5-second timeout.** If query takes longer, treat as no-match.
29
-
30
- ### 2. Evaluate Result
31
-
32
- **If tool unavailable or timeout:**
33
- - Set `ecosystem_status: skip`
34
- - Proceed silently to step 3 (auto-proceed, no message to user)
35
-
36
- **If no match found:**
37
- - Set `ecosystem_status: no-match`
38
- - Auto-proceed silently to step 3. Do not display any message — absence of a match is the expected case.
39
-
40
- **If match found:**
41
- - Set `ecosystem_status: match`
42
- - Display match details and present conditional menu:
43
-
44
- "**Existing official skill found for {repo_name}.**
45
-
46
- **Skill:** {matched_skill_name}
47
- **Source:** agentskills.io
48
- **Authority:** official
49
-
50
- An official skill already exists. You can:
51
-
52
- **[P] Proceed** — Compile a custom community skill anyway (different scope or customization)
53
- **[I] Install** — Install the existing official skill instead (exits this workflow)
54
- **[A] Abort** — Cancel compilation"
55
-
56
- ### 3. Handle Match Menu (only when a match was found)
57
-
58
- #### Menu Handling Logic:
59
-
60
- - IF P: Set `ecosystem_status: match-proceed`, then load, read entire file, then execute {nextStepFile}
61
- - IF I: Display install instructions for the official skill, emit the HARD HALT envelope per `references/halt-contract.md` (`phase: "ecosystem-check"`, `error.code: "ecosystem-redirect"`, `error.message: "User opted to install existing official skill instead of compiling a custom community skill."`, `skill_package: null`), exit with code 8 (ecosystem-redirect). Skill package is unknown at this phase — no on-disk result file is written.
62
- - IF A: Display "Compilation cancelled.", emit the HARD HALT envelope (`phase: "ecosystem-check"`, `error.code: "user-cancelled"`, `error.message: "User aborted at ecosystem-match gate."`, `skill_package: null`), exit with code 6 (user-cancelled). Skill package is unknown at this phase — no on-disk result file is written.
63
- - IF Any other: help user, then redisplay the match menu
64
-
65
- #### Gate:
66
-
67
- - **GATE [default: P]** — If `{headless_mode}` and match found: auto-proceed with [P] Proceed (compile custom skill anyway), log: "headless: ecosystem match found, auto-proceeding with custom compilation"
68
-
69
- ### 4. Auto-Proceed (No Match or Skip)
15
+ agentskills.io has no registry API to ask whether an official skill already covers `{repo_name}`, so make no query and no web search (a search hit cannot show that a skill is official), say nothing, and go on as IF P does.
70
16
 
71
- For no-match and skip, load and execute {nextStepFile} to proceed to source extraction.
17
+ Once a registry API lists an official skill for `{repo_name}`, name it and offer: [P] Proceed, compiling a custom community skill anyway · [I] Install the official skill instead, which ends this workflow · [A] Abort. Answer anything else by helping, then offer again.
72
18
 
19
+ - IF P: when `{headless_mode}` is true, print this step's `done` event and step 3's `start` event (`references/halt-contract.md`); then load, read entire file, then execute {nextStepFile}
20
+ - IF I: Display install instructions for the official skill, then HARD HALT with **exit code 8 (ecosystem-redirect)**: stage `{"phase": "ecosystem-check", "halt_reason": "ecosystem-redirect", "reason": "User opted to install existing official skill instead of compiling a custom community skill.", "skill_package": null}` as `{run_dir}/halt.json` and run `uv run {emitEnvelopeHelper} emit-halt --workflow skf-quick-skill --run-dir "{run_dir}" --target stderr < "{run_dir}/halt.json"` (`references/halt-contract.md`). The skill package is unknown at this phase, so no result file is written.
21
+ - IF A: Display "Compilation cancelled.", then HARD HALT with **exit code 6 (user-cancelled)**: stage `{"phase": "ecosystem-check", "halt_reason": "user-cancelled", "reason": "User aborted at ecosystem-match gate.", "skill_package": null}` as `{run_dir}/halt.json` and run `uv run {emitEnvelopeHelper} emit-halt --workflow skf-quick-skill --run-dir "{run_dir}" --target stderr < "{run_dir}/halt.json"`. No result file is written.
22
+ - **GATE [default: P]**: if `{headless_mode}` and match found, auto-proceed with [P] Proceed (compile custom skill anyway), log "headless: ecosystem match found, auto-proceeding with custom compilation", and record the decision: stage `{"gate": "ecosystem-check.ecosystem-match", "default_action": "P", "taken_action": "P", "reason": "headless: compiled a custom skill beside the official one"}` as `{run_dir}/decision.json` and run `uv run {emitEnvelopeHelper} record --workflow skf-quick-skill --run-dir "{run_dir}" --decision < "{run_dir}/decision.json"`, then go on as IF P does, its events included.
@@ -11,35 +11,35 @@ atomicWriteProbeOrder:
11
11
 
12
12
  ## STEP GOAL:
13
13
 
14
- To finalize the skill by creating the active-version pointer, displaying the completion summary, and writing the result contract. Deliverables (SKILL.md, context-snippet.md, metadata.json) were already written in step 5 so that validation could run against files on disk; this step only performs the post-write finalization.
14
+ To finalize the skill by creating the active-version pointer, displaying the completion summary, and emitting the result envelope and result contract.
15
15
 
16
16
  ## Rules
17
17
 
18
18
  - Do not rewrite deliverables — they were written and validated in step 5
19
- - Create the active pointer via the shared helper — never `rm` + `ln -s` manually
20
- - Result contract writing is mandatory (pipeline consumers depend on it)
19
+ - Emit the result envelope and contract through the shared emitter, never by hand; when it is missing or fails twice, say the contract was not written and go on (§3)
20
+ - A HARD HALT prints, after its envelope, this step's `halt` event when `{headless_mode}` is true. Under `--batch` it ends only this target: then return to `references/batch-mode.md` §3, even when the halt reads as the end of the run (`references/halt-contract.md`).
21
21
 
22
22
  ## Steps
23
23
 
24
24
  ### 1. Create Active Pointer (atomic flip, Windows-safe)
25
25
 
26
- **If `{overrides.no_active_pointer}` is true** — skip the helper invocation entirely. Log: "Active pointer: skipped per `--no-active-pointer` override." Do not update `{skill_group}/active`. Proceed to §2 with the active-pointer line omitted from the completion summary and the outputs payload.
26
+ **If `{overrides.no_active_pointer}` is true**, skip the helper invocation entirely. Log: "Active pointer: skipped per `--no-active-pointer` override." Do not update `{skill_group}/active`, and set `{active_pointer}` to `skipped-no-active-pointer`. Proceed to §2 with the active-pointer line omitted from the completion summary and the outputs payload.
27
27
 
28
- `{skill_group}` and `{skill_package}` were computed in step 5 §1 from `{skills_output_folder}`, `{repo_name}`, and `{version}`; `{version}` was resolved from the extraction inventory. Reuse the same values here — do not recompute.
28
+ `{skill_group}` and `{skill_package}` were computed in step 5 §1 from `{skills_output_folder}`, `{repo_name}`, and `{version}`; `{version}` is the `version` of the `metadata.json` step 5 installed.
29
29
 
30
- Create or update the `active` pointer at `{skill_group}/active` pointing to `{version}` using the shared atomic-flip helper. The helper acquires an `flock` on `{skill_group}/active.skf-lock`, refuses to replace a non-link at `{skill_group}/active` (protecting against accidental `rm -rf` of a real directory), and uses a rename-over-symlink pattern so the update is atomic from a concurrent reader's perspective. On Windows the helper automatically falls back to a directory junction (`mklink /J`) when `os.symlink` fails with `PRIVILEGE_NOT_HELD` / `ACCESS_DENIED` — junctions require no admin elevation and resolve identically for `skf-skill-inventory`'s consumers:
30
+ Point `{skill_group}/active` at `{version}` with the shared helper.
31
31
 
32
- **Resolve `{atomicWriteHelper}`** from `{atomicWriteProbeOrder}`; first existing path wins. If no candidate exists, skip the flip the same way `--no-active-pointer` does: log "Active pointer: skipped — atomic-write helper unavailable", omit the active-pointer line from the completion summary and outputs, and record `active_pointer: "skipped-helper-missing"` in the result-contract summary (§3) so consumers see why the pointer is absent. The deliverables are already on disk, so a missing helper degrades to "no pointer" rather than a failed run. There is no manual fallback: a hand-rolled `rm` + `ln -s` loses the helper's atomicity and non-link guard, risking a half-flipped pointer or an `rm -rf` into a real directory.
32
+ **Resolve `{atomicWriteHelper}`** from `{atomicWriteProbeOrder}`; first existing path wins. If no candidate exists, skip the flip the same way `--no-active-pointer` does: log "Active pointer: skipped, atomic-write helper unavailable", omit the active-pointer line from the completion summary and outputs, and set `{active_pointer}` to `skipped-helper-missing`, which the result-contract summary (§3) carries so consumers see why the pointer is absent. This branch is reached only when `skf-atomic-write.py` disappeared after step 5, whose metadata.json install halts without it. There is no manual fallback: a hand-rolled `rm` + `ln -s` loses the helper's atomicity and non-link guard, risking a half-flipped pointer or an `rm -rf` into a real directory.
33
33
 
34
34
  ```bash
35
- python3 {atomicWriteHelper} flip-link \
36
- --link {skill_group}/active \
37
- --target {version}
35
+ uv run {atomicWriteHelper} flip-link \
36
+ --link "{skill_group}/active" \
37
+ --target "{version}"
38
38
  ```
39
39
 
40
- The helper returns non-zero (helper exit 2) if `{skill_group}/active` already exists as a real directory or file rather than a link — in that case, HARD HALT the workflow with **exit code 7 (finalize-blocked)** per the exit-code map in `references/halt-contract.md`: "Refusing to flip `{skill_group}/active` — existing path is not a symlink or junction. Investigate manually; expected a link pointing at a version directory." Before exiting, emit the error result contract per `references/halt-contract.md` (`phase: "finalize"`, `error.code: "finalize-blocked"`, `skill_package` set, `outputs` listing the deliverables already on disk from step 5). A common cause on Windows is a prior run that executed `ln -s` under git-bash without Developer Mode enabled, which silently wrote a full directory copy; remove that copy and retry.
40
+ On exit 0 the helper prints `{"link": …, "points_to": …, "kind": …, "status": "ok"}` on stdout. On any other exit, HARD HALT the workflow with **exit code 7 (finalize-blocked)**: "Refusing to flip `{skill_group}/active`: {the `message` of the helper's `{"status": "error", "message": …}` stderr line (something that is not a link is at `{skill_group}/active`, or another process holds its lock), else its stderr}." Stage `{"phase": "finalize", "halt_reason": "finalize-blocked", "reason": "Refusing to flip {skill_group}/active: <the helper's message>", "skill_package": "{skill_package}", "outputs": {"skill_md": "{skill_package}/SKILL.md", "context_snippet": "{skill_package}/context-snippet.md", "metadata": "{skill_package}/metadata.json"}}` as `{run_dir}/halt.json` (`context_snippet` left out under `--skip-snippet`) and run `uv run {emitEnvelopeHelper} emit-halt --workflow skf-quick-skill --run-dir "{run_dir}" --result-dir "{skill_package}" --target stderr < "{run_dir}/halt.json"` (`references/halt-contract.md`). When a real folder is at `{skill_group}/active`, a common cause on Windows is a prior run that executed `ln -s` under git-bash without Developer Mode enabled, which silently wrote a full directory copy: remove that copy and retry.
41
41
 
42
- Confirm: "Active pointer: {skill_group}/active -> {version} ({kind})" where `{kind}` is `symlink` or `junction` as returned by the helper.
42
+ Confirm: "Active pointer: {skill_group}/active -> {version} ({kind})" where `{kind}` is `symlink` or `junction` as returned by the helper, and set `{active_pointer}` to that `{kind}`.
43
43
 
44
44
  ### 2. Display Completion Summary
45
45
 
@@ -51,6 +51,8 @@ Confirm: "Active pointer: {skill_group}/active -> {version} ({kind})" where `{ki
51
51
  **Authority:** community
52
52
  **Confidence:** {extraction confidence}
53
53
  {If `scope_hint` is non-empty, add:} **Scope:** {scope_hint}
54
+ {If step 3 recorded a `repo_shape`, add:} **Repo shape:** {repo_shape}
55
+ {If it is `skills-module`, add:} **Skills:** {skill count} skills and {menu code count} menu codes, documented as the exports below
54
56
 
55
57
  **Files written:**
56
58
  - `{skill_package}/SKILL.md`
@@ -58,6 +60,8 @@ Confirm: "Active pointer: {skill_group}/active -> {version} ({kind})" where `{ki
58
60
  - `{skill_package}/metadata.json`
59
61
  - `{skill_group}/active` -> `{version}` (omit this line when `--no-active-pointer` was set)
60
62
 
63
+ {If step 5 §1 set `{replaced_build}`, add:} **Replaced:** the `{replaced_build}` build of v{version}. Its forge data, `{forge_data_folder}/{repo_name}/{version}/`, is left in place: remove it yourself once you no longer need it.
64
+
61
65
  **Exports documented:** {count}
62
66
  **Validation:** {pass / N issues (advisory)}
63
67
 
@@ -70,18 +74,65 @@ Confirm: "Active pointer: {skill_group}/active -> {version} ({kind})" where `{ki
70
74
 
71
75
  **Note:** This is a best-effort community skill. For deeper analysis with AST-verified exports and provenance tracking, use the full **create-skill** workflow with a skill brief."
72
76
 
73
- ### 3. Result Contract
77
+ ### 3. Result Envelope and Result Contract
78
+
79
+ Stage the run's result payload through a quoted heredoc, then run the shared emitter, which prints the success envelope and writes the result contract:
80
+
81
+ ```bash
82
+ cat > "{run_dir}/result-context.json" <<'SKF_JSON'
83
+ {
84
+ "status": "success",
85
+ "skill_package": "{skill_package}",
86
+ "outputs": {"skill_md": "{skill_package}/SKILL.md", "context_snippet": "{skill_package}/context-snippet.md", "metadata": "{skill_package}/metadata.json", "active_pointer": "{skill_group}/active"},
87
+ "summary": {
88
+ "skill_name": "{repo_name}",
89
+ "version": "{version}",
90
+ "language": "{language}",
91
+ "exports_documented": {export count},
92
+ "quality_score": {quality_score},
93
+ "confidence": "{extraction confidence}",
94
+ "repo_shape": {repo_shape},
95
+ "language_resolution": {language_resolution},
96
+ "detected_languages": {detected_languages},
97
+ "zero_exports_rescue": {zero_exports_rescue},
98
+ "active_pointer": "{active_pointer}",
99
+ "validation_issues": {validation_issues}
100
+ },
101
+ "result_contract": {
102
+ "skill": "skf-quick-skill",
103
+ "outputs": [
104
+ {"type": "skill", "path": "{skill_package}/SKILL.md"},
105
+ {"type": "skill", "path": "{skill_package}/context-snippet.md"},
106
+ {"type": "skill", "path": "{skill_package}/metadata.json"}
107
+ ]
108
+ }
109
+ }
110
+ SKF_JSON
111
+ uv run {emitEnvelopeHelper} emit --workflow skf-quick-skill --run-dir "{run_dir}" --result-dir "{skill_package}" < "{run_dir}/result-context.json"
112
+ ```
113
+
114
+ This list is the summary, once: `skill_name`, `version`, `language`, `exports_documented` (the export count), `quality_score` and `validation_issues` (step 5, the object `{"skill_md": <n>, "context_snippet": <n>, "metadata": <n>, "security": <n>}`), `confidence` and `repo_shape` (step 3, the shape null when it recorded none), `language_resolution` and `detected_languages` (step 1), `zero_exports_rescue` (step 3 §4.5, else null) and `active_pointer` (§1). Write each value as JSON: a string in double quotes with any `"` or `\` escaped, every path absolute with `/`, and `null` for a value the run did not record. Leave the snippet out of both `outputs` under `--skip-snippet`, and `outputs.active_pointer` out when §1 flipped no pointer.
74
115
 
75
- Write the result contract per `shared/references/output-contract-schema.md`: the per-run record at `{skill_package}/quick-skill-result-{YYYYMMDD-HHmmss}.json` (UTC timestamp, resolution to seconds) and a copy at `{skill_package}/quick-skill-result-latest.json` (stable path for pipeline consumers — copy, not symlink). Include `SKILL.md`, `context-snippet.md`, and `metadata.json` paths in `outputs` and export count in `summary`.
116
+ The emitter writes the result contract from `result_contract`, with the payload's own `status` and `summary`, so neither is typed twice (the per-run record `{skill_package}/quick-skill-result-{YYYYMMDD-HHmmss}.json` and its copy `quick-skill-result-latest.json`, the stable path for pipeline consumers) and prints one line on stdout, `SKF_QUICK_SKILL_RESULT_JSON: {...}`. In a headless single-target run, bind `{result_envelope_line}` ← that line and do not display it here: the shared health check displays it verbatim as the run's last line, so a `claude -p` caller reads the envelope as the final message. Otherwise (an interactive run, or a `--batch` target) display it verbatim as its own line. If it exits non-zero, fix `result-context.json` once (its `message` names the problem) and run it again; if it still fails, or no path resolved for `{emitEnvelopeHelper}`, leave `{result_envelope_line}` empty, say that the result contract was not written and why, and go on.
76
117
 
77
- **Post-completion hook (optional).** If `{onCompleteCommand}` is non-empty (resolved at SKILL.md On Activation §3 from `workflow.on_complete`), invoke it after the result contract is finalized:
118
+ **Post-completion hook (optional).** If `{onCompleteCommand}` is non-empty (resolved at SKILL.md On Activation §3 from `workflow.on_complete`) and the emitter wrote the result contract (the line it printed has a non-null `result_path` and no `result_file_write_failed` warning naming `quick-skill-result-latest.json`), invoke it after the result contract is finalized:
78
119
 
79
120
  ```bash
80
- {onCompleteCommand} --skill-package={skill_package}
121
+ {onCompleteCommand} --result-path={skill_package}/quick-skill-result-latest.json
81
122
  ```
82
123
 
83
- Log success/failure but never fail the workflow on a hook error — the skill is already written. The hook runs last so a git-add, registry registration, or notifier sees a complete package. When `{onCompleteCommand}` is empty (bundled default), skip the invocation entirely.
124
+ When the emitter failed twice, no path resolved for `{emitEnvelopeHelper}`, `result_path` is null, or a `result_file_write_failed` warning names `quick-skill-result-latest.json` (the copy alone failed), skip the hook and say so: "Post-completion hook skipped: `quick-skill-result-latest.json` was not written." The hook never gets a missing file or an earlier run's `-latest` copy. Log success/failure but never fail the workflow on a hook error: the skill is already written. The hook runs last so a git-add, registry registration, or notifier sees a complete package. Under `--batch` it runs once per target that reaches this section.
125
+
126
+ In a single-target run, then delete the run folder, which a finished run no longer needs: the files step 3 fetched into it, and the files the steps staged (if `rmdir` reports it is not empty, leave it). The `case` guard deletes nothing unless the path is a quick-skill run folder:
127
+
128
+ ```bash
129
+ case "{run_dir}" in */.skf-run/skf-quick-skill-*) rm -rf "{run_dir}/src" && rm -f "{run_dir}"/*.json "{run_dir}"/*.jsonl "{run_dir}"/*.txt && rmdir "{run_dir}" ;; esac
130
+ ```
131
+
132
+ Under `--batch`, leave it: batch mode §3 records the target from it, then removes it.
84
133
 
85
134
  ### 4. Chain to Health Check
86
135
 
87
- Once the active pointer, completion summary, result contract, and any post-completion hook are done, load and execute {nextStepFile}. Do not stop here — health-check is the true terminal step even though the summary reads as final.
136
+ **Single target.** Once the active pointer, completion summary, result envelope, any post-completion hook and the run folder's removal are done, print this step's `done` event and step 7's `start` event when `{headless_mode}` is true (`references/halt-contract.md`), then load and execute {nextStepFile}. Do not stop here: health-check is the true terminal step even though the summary reads as final.
137
+
138
+ **Under `--batch`.** Print this step's `done` event, then return to `references/batch-mode.md` §3 instead of {nextStepFile}: control returns there even though this step reads as the end of the run. The health check runs once, after the batch summary.
@@ -2,7 +2,7 @@
2
2
 
3
3
  # HARD HALT Contract
4
4
 
5
- The exit-code map and error-result envelope every step emits on a HARD HALT. Any step loads this file on its failure path, so the wire format is available even if SKILL.md has been compacted mid-run.
5
+ The exit-code map, the envelope every HARD HALT emits, the headless progress events and the `--batch` rule. Each HARD HALT in the stage files names its phase, `halt_reason`, exit code and emit command, and each stage's Rules carry its `halt` event and the `--batch` return, so a halt keeps its wire format even when SKILL.md or this file was compacted away.
6
6
 
7
7
  ## Exit Codes
8
8
 
@@ -11,44 +11,56 @@ Every HARD HALT in this workflow exits with a stable, documented code so headles
11
11
  | Code | Meaning | Raised by |
12
12
  | ---- | ---------------------- | ----------------------------------------------------------- |
13
13
  | 0 | success | step 7 (terminal) |
14
- | 3 | resolution-failure | step 1 (prose input §2, registry chain §3, version-tag miss §3a, language abort §4); step 3 (non-library shape §1.5, zero-exports §4.5) |
15
- | 4 | write-failure | step 5 §2 (deliverable write failed) |
16
- | 5 | overwrite-cancelled | step 5 §1 (user selected [N]) |
17
- | 6 | user-cancelled | step 1 §1 ([X] Cancel and exit, or cancel-line affordance); step 2 §3 ([A] Abort at ecosystem-match gate); step 4 §6 (user selected [Q]) |
18
- | 7 | finalize-blocked | step 6 §1 (active-pointer flip refused — non-link in place) |
19
- | 8 | ecosystem-redirect | step 2 §3 ([I] Install at ecosystem-match gate — user opted to install the existing official skill instead of compiling a custom community skill) |
14
+ | 2 | input-invalid | batch mode, before any target runs (`--description`, `--exports`, `--language-hint` or `--scope-hint` passed with `--batch`; §1: a batch file it cannot read, or `skf-quick-batch.py` missing); step 1 §1 (a headless run with no target) |
15
+ | 3 | resolution-failure | SKILL.md On Activation step 1 (`python3` or `uv` missing); a shipped helper missing, named in the message and in `details.cause` (step 3: `skf-github-fetch.py`, `skf-skills-module.py` §1, `skf-extract-public-api.py` §2; step 5: `skf-atomic-write.py` §2, `skf-validate-frontmatter.py` §4 when skill-check is unavailable, `skf-validate-output.py` §5); step 1 (package resolver missing or failing §1b, a target that is no GitHub repository or package §2, registry chain §3, version tag missing or not checkable §3a, file listing unreadable, language detector missing or failing, language abort or no language found §4); step 3 (non-library shape §1.5, zero-exports §4.5) |
16
+ | 4 | write-failure | SKILL.md On Activation step 1 (the run folder cannot be created); batch mode §1 (the batch run folder cannot be written); step 5 §2 (deliverable write failed) |
17
+ | 5 | overwrite-cancelled | step 5 §1 (user selected [N], or a headless run reached a version another SKF workflow built; `details.existing_generator` names its generator) |
18
+ | 6 | user-cancelled | step 1 §1 ([X] Cancel and exit, or cancel-line affordance) and §3 ([X] at the ambiguous-name gate); step 2 ([A] Abort at ecosystem-match gate); step 4 §6 (user selected [Q]) |
19
+ | 7 | finalize-blocked | step 6 §1 (the flip helper refused or failed: something that is not a link is at `{skill_group}/active`, or another process holds its lock) |
20
+ | 8 | ecosystem-redirect | step 2 ([I] Install at ecosystem-match gate: user opted to install the existing official skill instead of compiling a custom community skill) |
21
+ | 9 | state-conflict | step 5 §1 (ownership check: the skill folder or the version folder it writes is not SKF output, or SKF cannot check it → error.code `not-skf-output`; an SKF skill still in the flat layout → `flat-layout`) |
20
22
 
21
23
  ## Result Contract on HARD HALT
22
24
 
23
- In addition to the success-variant result contract written by step 6 §3, every HARD HALT must surface an **error variant** so headless automators don't silently break when `quick-skill-result-latest.json` is missing on failed runs.
25
+ Every HARD HALT emits an **error envelope** through the shared emitter, `{emitEnvelopeHelper}`, so headless automators never meet a failed run with no result, except SKILL.md On Activation's halt for a missing `python3` or `uv`, which the emitter needs: that halt displays its message alone. SKILL.md On Activation step 1 resolved the emitter; when a compaction lost it, it is the first existing path of `{project-root}/_bmad/skf/shared/scripts/skf-emit-result-envelope.py` and `{project-root}/src/shared/scripts/skf-emit-result-envelope.py`. Stage the halt payload as `{run_dir}/halt.json` through a quoted heredoc, then run the emitter:
24
26
 
25
- **Always (every HARD HALT, regardless of phase)** — emit a single line on **stderr**:
26
-
27
- ```
28
- SKF_QUICK_SKILL_RESULT_JSON: {"status":"error","exit_code":<N>,"phase":"<slug>","error":{"code":"<class>","message":"<short>"},"outputs":{},"summary":{},"skill_package":"<path-or-null>"}
27
+ ```bash
28
+ cat > "{run_dir}/halt.json" <<'SKF_JSON'
29
+ {"phase": "<step slug>", "halt_reason": "<code>", "reason": "<the halt message, one line>", "skill_package": null}
30
+ SKF_JSON
31
+ uv run {emitEnvelopeHelper} emit-halt --workflow skf-quick-skill --run-dir "{run_dir}" --target stderr < "{run_dir}/halt.json"
29
32
  ```
30
33
 
31
- One line, no pretty-print. Matches the prefix-and-envelope convention used by `skf-emit-result-envelope.py`.
34
+ - `phase`: the step's slug (`resolve-target`, `ecosystem-check`, `quick-extract`, `compile`, `write-and-validate`, `finalize`), `on-activation` for a halt before the run starts (SKILL.md On Activation, and batch mode's refusal of `--description` and `--exports` and of the hint flags), or `batch-mode` for batch mode §1.
35
+ - `halt_reason`: the failure class the halt names: the Meaning of its exit code in the table above, or `not-skf-output` or `flat-layout` for exit 9. The emitter derives `exit_code` from it.
36
+ - `reason`: the message the step displayed, as one line (its first sentence when it runs longer); it becomes `error.message`. Escape `"` and `\` in it as JSON requires.
37
+ - `skill_package`: the absolute `{skill_package}` once step 5 §1 computed it, else `null`.
38
+ - `outputs` (optional): the files already on disk, as `{"skill_md": ..., "context_snippet": ..., "metadata": ...}` paths.
39
+ - `details` (only when the halt names them): the halt's context as an object, such as the folder a refusal names or the file a failed write named. The emitter puts it in the envelope's `error.details`, beside the `code` and `message` it builds from `halt_reason` and `reason`, so no halt types an `error` object.
40
+
41
+ The emitter prints one line on stderr, `SKF_QUICK_SKILL_RESULT_JSON: {...}`: display it verbatim. If it exits non-zero, fix `halt.json` once (its `message` names the problem) and run it again; if it still fails, or no path resolved for `{emitEnvelopeHelper}`, display the halt message alone.
32
42
 
33
- **Additionally, when `{skill_package}` is known** (HALT at step 5 §1 onward) — write the same JSON object (without the `SKF_QUICK_SKILL_RESULT_JSON: ` prefix) to disk:
43
+ **Additionally, when `{skill_package}/metadata.json` exists** (HALT at step 5 §1 onward, except the step 5 §1 ownership halt, which writes nothing on disk: `{skill_package}` would sit in a folder SKF did not generate), the command adds `--result-dir "{skill_package}"`, and the emitter also writes the envelope (without the `SKF_QUICK_SKILL_RESULT_JSON: ` prefix) to disk:
34
44
 
35
45
  ```
36
46
  {skill_package}/quick-skill-result-{YYYYMMDD-HHmmss}.json
37
47
  {skill_package}/quick-skill-result-latest.json (copy, not symlink)
38
48
  ```
39
49
 
40
- so consumers that hardcode the `-latest.json` path see a deterministic file even on failed runs. HALTs at step 1/02/03/04 cannot write to disk because `{skill_package}` is computed only in step 5 §1; for those, the stderr envelope plus exit code is the contract.
41
-
42
- **Schema:**
43
-
44
- | Field | Type | Notes |
45
- | --------------- | -------------- | ----------------------------------------------------------------------------------------------------------- |
46
- | `status` | string | always `"error"` for HARD HALTs |
47
- | `exit_code` | integer | matches the Exit Codes table above |
48
- | `phase` | string | step slug where the HALT occurred (e.g. `resolve-target`, `compile`) |
49
- | `error.code` | string | one of: `resolution-failure`, `write-failure`, `overwrite-cancelled`, `user-cancelled`, `finalize-blocked`, `ecosystem-redirect` |
50
- | `error.message` | string | the user-facing message that was displayed |
51
- | `error.details` | any | optional — phase-specific context (e.g. the failed file path) |
52
- | `outputs` | object | empty `{}` on early HALTs; partial when files were already written |
53
- | `summary` | object | empty `{}` on early HALTs |
54
- | `skill_package` | string \| null | absolute path when known, `null` when HALT preceded step 5 §1 |
50
+ so consumers that hardcode the `-latest.json` path see a deterministic file even on failed runs. Before step 5 §1 computes `{skill_package}`, the stderr line and the exit code are the whole contract. A HALT while `{skill_package}` has no `metadata.json` (a failed first write in step 5 §2, for example) writes nothing on disk either: a package holding only result files is not SKF output, so the next run's ownership check would refuse it.
51
+
52
+ **Schema:** `shared/scripts/schemas/skf-quick-skill-result-envelope.v1.json` (installed under `{project-root}/_bmad/skf/`).
53
+
54
+ ## Headless Events
55
+
56
+ When `{headless_mode}` is true, each step prints one-line JSON progress events on stderr (one line each, never pretty-printed), so a pipeline can follow a run live:
57
+
58
+ - when the step starts: `{"step":N,"name":"<slug>","status":"start"}`
59
+ - just before it chains to its `nextStepFile`: `{"step":N,"name":"<slug>","status":"done"}`
60
+ - at a HARD HALT, in place of `done`: `{"step":N,"name":"<slug>","status":"halt","exit":<code>}`
61
+
62
+ `N` and `<slug>`: 1 `resolve-target`, 2 `ecosystem-check`, 3 `quick-extract`, 4 `compile`, 5 `write-and-validate`, 6 `finalize`, 7 `health-check`. A `--batch` run adds the per-target events of `references/batch-mode.md`.
63
+
64
+ ## In `--batch`
65
+
66
+ A HARD HALT in steps 1 to 6 ends the current target, not the batch. After its envelope line and `halt` event, return to `references/batch-mode.md` §3, which records the target and prints its `fail` event: control returns there even when the halt message reads as the end of the run, so a target's halt never exits the process. The batch then takes its next target, or, under `--fail-fast`, writes its summary. A halt before the first target (SKILL.md On Activation, batch mode's refusal of `--description` and `--exports`, or batch mode §1) ends the run itself, with no batch summary.
@@ -11,13 +11,15 @@ nextStepFile: 'shared/health-check.md'
11
11
 
12
12
  ## STEP GOAL:
13
13
 
14
- Chain to the shared workflow self-improvement health check at `{nextStepFile}`. This is the terminal step of quick-skill — after the shared health check completes, the workflow is fully done.
14
+ Chain to the shared workflow self-improvement health check at `{nextStepFile}`. This is the terminal step of quick-skill: after the shared health check completes, the workflow is fully done. Under `--batch` it runs once per batch, after `references/batch-mode.md` §4 wrote the batch summary, never after a single target.
15
+
16
+ In a headless single-target run step 6 §3 bound `{result_envelope_line}` to the `SKF_QUICK_SKILL_RESULT_JSON` line without displaying it: the shared health check displays that line verbatim as the run's last line wherever it stops, so a `claude -p` caller reads the envelope as the final message.
15
17
 
16
18
  ## Rules
17
19
 
18
20
  - No user-facing reports, file writes, or result contracts in this step — those belong in step 6
19
- - Delegate directly to `{nextStepFile}` with no additional commentary or intervening action
21
+ - Delegate directly to `{nextStepFile}` with no additional commentary or other action, except the headless `done` event below
20
22
 
21
23
  ## Steps
22
24
 
23
- Load `{nextStepFile}`, read it fully, then proceed to execute it.
25
+ When `{headless_mode}` is true, print this step's `done` event (`references/halt-contract.md`). Load `{nextStepFile}`, read it fully, then proceed to execute it.