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
@@ -2,7 +2,19 @@
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://github.com/armelhbobdad/bmad-module-skill-forge/src/shared/scripts/schemas/skf-setup-result-envelope.v1.json",
4
4
  "title": "SKF_SETUP_RESULT_JSON envelope (v1)",
5
- "description": "Single-line JSON document emitted by skf-setup step 4 §4 when {headless_mode} is true, prefixed with the literal 'SKF_SETUP_RESULT_JSON: '. Pipelines grep one line out of the workflow log without parsing ASCII-art and without racing the forge-tier.yaml writer. Schema added in PR #247, extended in PR #248 (header / outputs / failure modes), extended again in this PR with previous_tier / tier_changed / tools_added / tools_removed / error.",
5
+ "description": "Single-line JSON document skf-setup displays when {headless_mode} or {quiet_mode} is true, prefixed with the literal 'SKF_SETUP_RESULT_JSON: '. Step 4 builds it at the end of a run (status success or tier_failure); a halt that names a phase builds a blocked one with the helper's emit-blocked subcommand. Pipelines grep one line out of the workflow log without parsing ASCII-art and without racing the forge-tier.yaml writer.",
6
+ "$defs": {
7
+ "skf-envelope": {
8
+ "description": "The shared emitter's settings for this workflow, read by skf-emit-result-envelope.py: the workflow, the line's prefix, the wrapper, the status a halt carries and the result file stem. Nothing in the schema references this entry, so it constrains no envelope.",
9
+ "const": {
10
+ "workflow": "skf-setup",
11
+ "prefix": "SKF_SETUP_RESULT_JSON",
12
+ "wrapper": "skf_setup",
13
+ "halt_status": "blocked",
14
+ "result_file": null
15
+ }
16
+ }
17
+ },
6
18
  "type": "object",
7
19
  "additionalProperties": false,
8
20
  "required": ["skf_setup"],
@@ -30,13 +42,13 @@
30
42
  "properties": {
31
43
  "status": {
32
44
  "type": "string",
33
- "enum": ["success", "tier_failure", "write_failure", "blocked"],
34
- "description": "Single-field outcome for pipeline branching. 'success' when no error and tier requirement (if any) is satisfied. 'tier_failure' when require_tier was set and is not satisfied. 'write_failure' when forge-tier.yaml or preferences.yaml could not be written. 'blocked' for any other halt that still produced an envelope (e.g. foreign ccc binary rejected pre-index)."
45
+ "enum": ["success", "tier_failure", "blocked"],
46
+ "description": "Single-field outcome for pipeline branching. 'success' when the run finished with no error and any required tier is satisfied. 'tier_failure' when --require-tier was set and is not satisfied. 'blocked' for any halt that still produced an envelope; error.phase names it, for example 'step 2:write-tools' or 'step 2:forge-data-dir' when forge-tier.yaml or the forge data folder could not be written."
35
47
  },
36
48
  "tier": {
37
49
  "type": "string",
38
50
  "enum": ["Quick", "Forge", "Forge+", "Deep"],
39
- "description": "Active capability tier this run."
51
+ "description": "Active capability tier this run. A blocked envelope carries 'Quick' as a placeholder."
40
52
  },
41
53
  "previous_tier": {
42
54
  "type": ["string", "null"],
@@ -73,7 +85,7 @@
73
85
  "config_path": {
74
86
  "type": "string",
75
87
  "minLength": 1,
76
- "description": "Absolute path to the forge-tier.yaml that this run wrote (or attempted to write — see error)."
88
+ "description": "Absolute path to the forge-tier.yaml this run wrote. A blocked envelope carries error.path here, or '<unknown — halt before config_path resolved>' when the halt has no path."
77
89
  },
78
90
  "ccc_index": {
79
91
  "type": "object",
@@ -92,10 +104,10 @@
92
104
  "type": "array",
93
105
  "items": {
94
106
  "type": "string",
95
- "enum": ["forge-tier.yaml", "preferences.yaml", "settings.yml", "ccc_index"]
107
+ "enum": ["forge-tier.yaml", "settings.yml", "ccc_index"]
96
108
  },
97
109
  "uniqueItems": true,
98
- "description": "Files actually written this run. Empty array when a write failure halted the run before any file was written."
110
+ "description": "Files written this run, as step 4 reports them. Setup never writes preferences.yaml: the installer creates it. A blocked envelope always carries an empty array, even when an earlier step had already written a file."
99
111
  },
100
112
  "tier_override_active": {
101
113
  "type": "boolean",
@@ -112,7 +124,7 @@
112
124
  "warnings": {
113
125
  "type": "array",
114
126
  "items": { "type": "string" },
115
- "description": "Non-fatal anomalies surfaced during the run. May include tier_override_invalid, tier_override_unsafe, ccc_exclusion_warnings entries, ccc_registry_stale_removed entries, qmd_daemon_stopped, ccc_indexing_failed, etc. Empty when none."
127
+ "description": "Non-fatal anomalies surfaced during the run. May include customization_resolver_unavailable, tier_override_invalid, tier_override_unsafe, ccc_exclusion_warnings entries, ccc_registry_stale_removed entries, qmd_daemon_stopped, tool_below_minimum entries (one per tool below its minimum version: '<tool> <version> (minimum <minimum>)'; a tier tool among them reads false under tools), ccc_indexing_failed, etc. Empty when none."
116
128
  },
117
129
  "error": {
118
130
  "oneOf": [
@@ -125,14 +137,18 @@
125
137
  "phase": {
126
138
  "type": "string",
127
139
  "minLength": 1,
128
- "description": "Step or operation that failed (e.g. 'write-config:forge-tier.yaml')."
140
+ "description": "The halt that produced the envelope, as <step>:<cause> (e.g. 'step 2:write-tools', 'on-activation:uv-missing')."
141
+ },
142
+ "path": {
143
+ "type": "string",
144
+ "minLength": 1,
145
+ "description": "Absolute path of the file or folder the halt concerns, or '<n/a>' when it has none."
129
146
  },
130
- "path": { "type": "string", "minLength": 1, "description": "Absolute path of the file the failed operation targeted." },
131
147
  "reason": { "type": "string", "minLength": 1, "description": "Human-readable error message." }
132
148
  }
133
149
  }
134
150
  ],
135
- "description": "Null on success. Object describing the failure when forge-tier.yaml or preferences.yaml could not be written. Pipelines branch on error !== null for 'exit code 2' semantics."
151
+ "description": "Null unless a halt produced the envelope; then the halt's phase, path and diagnostic. status is 'blocked' exactly when error is non-null, and the other fields of a blocked envelope are placeholders."
136
152
  }
137
153
  }
138
154
  }
@@ -0,0 +1,176 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/armelhbobdad/bmad-module-skill-forge/src/shared/scripts/schemas/skf-stack-result-envelope.v1.json",
4
+ "title": "SKF_STACK_RESULT_JSON envelope (v1)",
5
+ "description": "Single-line JSON document skf-create-stack-skill prints, prefixed with the literal 'SKF_STACK_RESULT_JSON: ': on stdout when step 9 (report) finishes, before it chains to the health check, and on stderr at every HARD HALT (status error). The shared emitter, skf-emit-result-envelope.py, builds every line from the payload a step stages in the run folder, folds in the auto-decisions and warnings the run recorded there, derives exit_code from halt_reason, stamps run_id and result_path, and checks the line against this schema, so the model never types it. The skill's references/invocation-contract.md lists each halt with its step; each halting step file shows the emit-halt command.",
6
+ "$defs": {
7
+ "skf-envelope": {
8
+ "description": "The shared emitter's settings for this workflow, read by skf-emit-result-envelope.py: the workflow, the line's prefix, the wrapper, the status a halt carries, the exit code of each halt_reason and the result file stem. Nothing in the schema references this entry, so it constrains no envelope.",
9
+ "const": {
10
+ "workflow": "skf-create-stack-skill",
11
+ "prefix": "SKF_STACK_RESULT_JSON",
12
+ "wrapper": null,
13
+ "halt_status": "error",
14
+ "exit_codes": {
15
+ "config-missing": 2,
16
+ "input-invalid": 2,
17
+ "no-manifests": 2,
18
+ "all-extractions-failed": 2,
19
+ "schema-version-mismatch": 2,
20
+ "unknown-verdict-token": 2,
21
+ "forge-tier-missing": 3,
22
+ "helper-missing": 3,
23
+ "resolution-failure": 3,
24
+ "write-failure": 4,
25
+ "not-skf-output": 5,
26
+ "flat-layout": 5,
27
+ "user-cancelled": 6
28
+ },
29
+ "success_exit_code": 0,
30
+ "result_file": "create-stack-skill-result"
31
+ }
32
+ }
33
+ },
34
+ "type": "object",
35
+ "additionalProperties": false,
36
+ "required": [
37
+ "status",
38
+ "skill_package",
39
+ "skill_name",
40
+ "stack_libraries",
41
+ "mode",
42
+ "quality_score",
43
+ "exit_code",
44
+ "halt_reason",
45
+ "run_id",
46
+ "result_path",
47
+ "headless_decisions",
48
+ "warnings"
49
+ ],
50
+ "properties": {
51
+ "status": {
52
+ "type": "string",
53
+ "enum": ["success", "error"],
54
+ "description": "'success' when step 9 finished the run, 'error' at every HARD HALT."
55
+ },
56
+ "skill_package": {
57
+ "type": ["string", "null"],
58
+ "description": "Absolute path of the committed stack package, {skills_output_folder}/{stack_name}/{version}/{stack_name}/. Null at every HARD HALT: no halt comes after step 7 committed the package."
59
+ },
60
+ "skill_name": {
61
+ "type": ["string", "null"],
62
+ "description": "The stack's published name, {stack_name}, as step 1 bound it. Null for a halt before step 1 bound it (config-missing, or a stack_name step 1 refused)."
63
+ },
64
+ "stack_libraries": {
65
+ "type": "array",
66
+ "items": { "type": "string", "minLength": 1 },
67
+ "description": "The libraries of the stack: dependency names in code mode, constituent skill names in compose mode. At a halt, the confirmed libraries when step 3 confirmed them, else []."
68
+ },
69
+ "mode": {
70
+ "type": ["string", "null"],
71
+ "enum": ["code", "compose", null],
72
+ "description": "The run's resolved mode; null for a halt before step 1 chose it."
73
+ },
74
+ "quality_score": {
75
+ "type": ["number", "null"],
76
+ "minimum": 0,
77
+ "description": "The skill-check score step 8 recorded for the committed package; null when skill-check did not run and at every halt. It is not a test-skill score: [TS] grades the stack."
78
+ },
79
+ "exit_code": {
80
+ "type": "integer",
81
+ "enum": [0, 2, 3, 4, 5, 6],
82
+ "description": "Derived from halt_reason: null gives 0; config-missing, input-invalid, no-manifests, all-extractions-failed, schema-version-mismatch and unknown-verdict-token 2; forge-tier-missing, helper-missing and resolution-failure 3; write-failure 4; not-skf-output and flat-layout 5; user-cancelled 6."
83
+ },
84
+ "halt_reason": {
85
+ "type": ["string", "null"],
86
+ "enum": [
87
+ null,
88
+ "config-missing",
89
+ "input-invalid",
90
+ "no-manifests",
91
+ "all-extractions-failed",
92
+ "schema-version-mismatch",
93
+ "unknown-verdict-token",
94
+ "forge-tier-missing",
95
+ "helper-missing",
96
+ "resolution-failure",
97
+ "write-failure",
98
+ "not-skf-output",
99
+ "flat-layout",
100
+ "user-cancelled"
101
+ ],
102
+ "description": "Null on success. The failure class of a HARD HALT, so a pipeline branches on it without parsing the message. helper-missing: a shared helper the run needs resolved to no path (re-install SKF)."
103
+ },
104
+ "error": {
105
+ "type": "object",
106
+ "additionalProperties": false,
107
+ "required": ["phase", "reason"],
108
+ "properties": {
109
+ "phase": {
110
+ "type": "string",
111
+ "minLength": 1,
112
+ "description": "Where the run halted: the step file and the check, for example 'detect-manifests:enumerate'."
113
+ },
114
+ "reason": {
115
+ "type": "string",
116
+ "minLength": 1,
117
+ "description": "The halt message the step displayed, on one line."
118
+ },
119
+ "path": {
120
+ "type": "string",
121
+ "minLength": 1,
122
+ "description": "Optional: the file or folder the halt names, such as a missing helper's probe path or the folder the ownership check refused."
123
+ }
124
+ },
125
+ "description": "Present at a HARD HALT only: where the run stopped and why."
126
+ },
127
+ "run_id": {
128
+ "type": ["string", "null"],
129
+ "description": "The run folder's id, stamped by the emitter from {run_dir}'s name; null for a halt before the run folder exists."
130
+ },
131
+ "result_path": {
132
+ "type": ["string", "null"],
133
+ "description": "The per-run create-stack-skill-result-<YYYYMMDD-HHmmss>.json the emitter wrote in {forge_version} on success, beside its -latest copy; null at a halt and when the write failed (warnings say why)."
134
+ },
135
+ "headless_decisions": {
136
+ "type": "array",
137
+ "items": {
138
+ "type": "object",
139
+ "additionalProperties": false,
140
+ "required": ["gate", "default_action", "taken_action", "reason"],
141
+ "properties": {
142
+ "gate": {
143
+ "type": "string",
144
+ "enum": ["init.compose-suggestion", "init.scan-root", "rank-and-confirm.scope", "compile-stack.review"],
145
+ "description": "The gate a headless run resolved by its default: step 1's compose suggestion and scan-scope question, step 3's scope gate and step 6's review gate. Each records its decision in the run sink the moment it decides."
146
+ },
147
+ "default_action": {
148
+ "type": "string",
149
+ "minLength": 1,
150
+ "description": "The gate's documented default action."
151
+ },
152
+ "taken_action": {
153
+ "type": "string",
154
+ "minLength": 1,
155
+ "description": "The action the run took; in a headless run it equals default_action."
156
+ },
157
+ "reason": {
158
+ "type": "string",
159
+ "minLength": 1,
160
+ "description": "Why, such as 'headless: kept the recommended scope'."
161
+ },
162
+ "evidence": {
163
+ "type": "object",
164
+ "description": "Optional gate data. The scope gate gives scope (the libraries kept) and dropped (each library the default left out, with its reason), so no library leaves the stack unrecorded."
165
+ }
166
+ }
167
+ },
168
+ "description": "One entry per gate the run resolved without asking, read from the run sink, so a halt reports the decisions taken before it. [] when there were none."
169
+ },
170
+ "warnings": {
171
+ "type": "array",
172
+ "items": { "type": "string", "minLength": 1 },
173
+ "description": "The run's workflow_warnings[], one '[<step>/<severity>] <code>: <message>' string each as the steps recorded them in the run sink, then any the emitter raised (result_file_write_failed, a sink line it could not read). [] when none."
174
+ }
175
+ }
176
+ }
@@ -0,0 +1,173 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/armelhbobdad/bmad-module-skill-forge/src/shared/scripts/schemas/skf-test-result-envelope.v1.json",
4
+ "title": "SKF_TEST_RESULT_JSON envelope (v1)",
5
+ "description": "Single-line JSON document skf-test-skill emits when {headless_mode} is true, prefixed with the literal 'SKF_TEST_RESULT_JSON: ': once when the report step has written the result contract (status success for a scored run, status error with halt_reason hard-gate-blocked for a run the hard gate blocked), and once at every HARD HALT (status error). The shared emitter, skf-emit-result-envelope.py, builds every line from the payload a stage stages in the run folder (the report step's from scripts/build-result-context.py), derives a halt's exit_code from halt_reason, stamps run_id and result_path, and checks the line against this schema, so the model never types it. A skill run cannot set the exit status of the agent that runs it, so automators read exit_code from this line or from skf-test-skill-result-latest.json. The skill's references/invocation-contract.md describes each halt.",
6
+ "$defs": {
7
+ "skf-envelope": {
8
+ "description": "The shared emitter's settings for this workflow, read by skf-emit-result-envelope.py: the workflow, the line's prefix, the wrapper, the status a halt carries, the exit code of each halt_reason and the result file stem. No success_exit_code: a scored run's exit_code follows its verdict (0 PASS, 2 FAIL, 3 INCONCLUSIVE, 4 pass-with-drift), which build-result-context.py derives. Nothing in the schema references this entry, so it constrains no envelope.",
9
+ "const": {
10
+ "workflow": "skf-test-skill",
11
+ "prefix": "SKF_TEST_RESULT_JSON",
12
+ "wrapper": null,
13
+ "halt_status": "error",
14
+ "exit_codes": {
15
+ "input-missing": 1,
16
+ "input-invalid": 1,
17
+ "runtime-missing": 1,
18
+ "helper-missing": 1,
19
+ "helper-failed": 1,
20
+ "write-failed": 1,
21
+ "target-inaccessible": 1,
22
+ "not-skf-output": 1,
23
+ "frontmatter-invalid": 1,
24
+ "forge-tier-missing": 1,
25
+ "workspace-drift": 1,
26
+ "another-run-active": 1,
27
+ "inventory-invalid": 1,
28
+ "indeterminate-surface": 1,
29
+ "step-completeness-violation": 1,
30
+ "report-anchor-missing": 1,
31
+ "health-check-missing": 1,
32
+ "hard-gate-blocked": 2
33
+ },
34
+ "result_file": "skf-test-skill-result"
35
+ }
36
+ }
37
+ },
38
+ "type": "object",
39
+ "additionalProperties": false,
40
+ "required": [
41
+ "status",
42
+ "skill_name",
43
+ "verdict",
44
+ "score",
45
+ "threshold",
46
+ "report_path",
47
+ "next_workflow",
48
+ "exit_code",
49
+ "halt_reason",
50
+ "run_id",
51
+ "result_path"
52
+ ],
53
+ "properties": {
54
+ "status": {
55
+ "type": "string",
56
+ "enum": ["success", "error"],
57
+ "description": "'success' when a scored run wrote its result contract (PASS, FAIL, INCONCLUSIVE or pass-with-drift: the workflow completed). 'error' on a HARD HALT, and on a run the hard gate blocked, which still writes the Gap Report and its FAIL result contract."
58
+ },
59
+ "skill_name": {
60
+ "type": ["string", "null"],
61
+ "minLength": 1,
62
+ "default": null,
63
+ "description": "The skill under test. Null only for a halt before the run had a name (a headless run given none halts input-missing)."
64
+ },
65
+ "verdict": {
66
+ "type": ["string", "null"],
67
+ "enum": ["PASS", "FAIL", "INCONCLUSIVE", "pass-with-drift", null],
68
+ "default": null,
69
+ "description": "The settled result: PASS, FAIL (a blocked run included), INCONCLUSIVE (the minimum-evidence floor) or pass-with-drift (a PASS under --allow-workspace-drift with drift observed, never exportable). Null on a halt before a verdict exists. The result file's summary.result spells the same verdict PASS, FAIL, INCONCLUSIVE or PASS_WITH_DRIFT."
70
+ },
71
+ "score": {
72
+ "type": ["number", "null"],
73
+ "minimum": 0,
74
+ "default": null,
75
+ "description": "The completeness score, in percent, from the scoring script. Null for a run the hard gate blocked (never scored) and on a halt."
76
+ },
77
+ "threshold": {
78
+ "type": ["number", "null"],
79
+ "minimum": 0,
80
+ "default": null,
81
+ "description": "The pass threshold the verdict was settled against, in percent: 80 when the threshold fallback fired (original_threshold holds the target). Null for a blocked run and on a halt."
82
+ },
83
+ "report_path": {
84
+ "type": ["string", "null"],
85
+ "minLength": 1,
86
+ "default": null,
87
+ "description": "The test report. A finished or blocked run names its published report, test-report-<skill>-<run_id>.md. A halt after the report was created names the in-progress copy, .skf-test-report-<skill>-<run_id>.md, which no consumer reads; null on a halt before it exists."
88
+ },
89
+ "next_workflow": {
90
+ "type": ["string", "null"],
91
+ "enum": ["export-skill", "update-skill", null],
92
+ "default": null,
93
+ "description": "\"export-skill\" only when verdict is PASS; \"update-skill\" for FAIL (a blocked run included) and pass-with-drift; null for INCONCLUSIVE (route to manual review) and on a halt."
94
+ },
95
+ "exit_code": {
96
+ "type": "integer",
97
+ "enum": [0, 1, 2, 3, 4],
98
+ "description": "The exit code the run settles on, for automators to branch on: 0 PASS, 2 FAIL (a blocked run's hard-gate-blocked included), 3 INCONCLUSIVE, 4 pass-with-drift, and 1 for every other halt_reason. A skill run cannot set the process exit status of the agent that runs it, so this field (or skf-test-skill-result-latest.json) is the place to read it."
99
+ },
100
+ "halt_reason": {
101
+ "type": ["string", "null"],
102
+ "enum": [
103
+ null,
104
+ "input-missing",
105
+ "input-invalid",
106
+ "runtime-missing",
107
+ "helper-missing",
108
+ "helper-failed",
109
+ "write-failed",
110
+ "target-inaccessible",
111
+ "not-skf-output",
112
+ "frontmatter-invalid",
113
+ "forge-tier-missing",
114
+ "workspace-drift",
115
+ "another-run-active",
116
+ "inventory-invalid",
117
+ "indeterminate-surface",
118
+ "step-completeness-violation",
119
+ "report-anchor-missing",
120
+ "health-check-missing",
121
+ "hard-gate-blocked"
122
+ ],
123
+ "description": "Null for a scored run. On a halt, the failure class: input-missing (headless with no skill name), input-invalid (a --tier value that names no tier), runtime-missing (python3 or uv is not on PATH), helper-missing (an SKF helper is not installed), helper-failed (a helper or scoring script exited with an error), write-failed (the run folder, the report or the result contract could not be written), target-inaccessible (no version of the skill to test), not-skf-output, frontmatter-invalid, forge-tier-missing, workspace-drift, another-run-active, inventory-invalid (the documented inventory failed its schema check or spot-check twice), indeterminate-surface (zero exports, or an empty stack surface: no score can be attached), step-completeness-violation, report-anchor-missing, health-check-missing; hard-gate-blocked for a run the hard gate blocked (verdict FAIL, exit 2)."
124
+ },
125
+ "run_id": {
126
+ "type": ["string", "null"],
127
+ "minLength": 1,
128
+ "description": "The run's id, stamped by the emitter from the run folder name: the UTC time the run took its lock and a random suffix, the {run_id} in the report's file name. Null for a halt before the run folder exists."
129
+ },
130
+ "result_path": {
131
+ "type": ["string", "null"],
132
+ "minLength": 1,
133
+ "description": "The per-run result file the emitter wrote in the version folder, skf-test-skill-result-<YYYYMMDD-HHmmss>.json (UTC; -2, -3 appended when a run took that second's name), beside its skf-test-skill-result-latest.json copy. Stamped by the emitter, never typed. Null on a halt, which writes no result file, and when the write failed (warnings say why)."
134
+ },
135
+ "threshold_fallback": {
136
+ "type": "boolean",
137
+ "const": true,
138
+ "description": "Present, and true, only when the threshold fallback accepted the run at the 80% floor; absent (never false or null) otherwise."
139
+ },
140
+ "original_threshold": {
141
+ "type": "number",
142
+ "minimum": 0,
143
+ "description": "The threshold the run was asked to meet, present only beside threshold_fallback."
144
+ },
145
+ "warnings": {
146
+ "type": "array",
147
+ "items": { "type": "string", "minLength": 1 },
148
+ "description": "Optional. Non-fatal anomalies the run recorded in its sink or the emitter raised, one string each, starting with its code: customization_resolver_unavailable when the customization resolver could not run, and result_file_write_failed when a result file could not be written. Present only when there is at least one."
149
+ },
150
+ "error": {
151
+ "type": "object",
152
+ "additionalProperties": false,
153
+ "required": ["phase", "reason"],
154
+ "properties": {
155
+ "phase": {
156
+ "type": "string",
157
+ "minLength": 1,
158
+ "description": "Where the run halted: the step and the check, for example 'init:runtime' or 'report:anchors'."
159
+ },
160
+ "reason": {
161
+ "type": "string",
162
+ "minLength": 1,
163
+ "description": "The halt message the step displayed, on one line."
164
+ },
165
+ "path": {
166
+ "type": "string",
167
+ "description": "Optional path the failed operation targeted."
168
+ }
169
+ },
170
+ "description": "Present on a HARD HALT only: where the run stopped and why. Pipelines branch on halt_reason and read error for the diagnostic."
171
+ }
172
+ }
173
+ }
@@ -2,7 +2,19 @@
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://github.com/armelhbobdad/bmad-module-skill-forge/src/shared/scripts/schemas/skf-update-result-envelope.v1.json",
4
4
  "title": "SKF_UPDATE_RESULT_JSON envelope (v1)",
5
- "description": "Single-line JSON document emitted by skf-update-skill step 7 (report) when {headless_mode} is true, prefixed with the literal 'SKF_UPDATE_RESULT_JSON: '. Pipelines branch on the envelope's top-level fields without parsing the human-readable report. The `headless_decisions[]` array surfaces every auto-resolved gate so non-interactive runs can be audited post-hoc — previously these were buried in the evidence report as free-form log lines. Schema added in PR #319.",
5
+ "description": "Single-line JSON document skf-update-skill emits when {headless_mode} is true, prefixed with the literal 'SKF_UPDATE_RESULT_JSON: ': once at the end of a run (step 6, report) and once at every halt. Every line, a halt's included, carries the skf_update wrapper, so pipelines branch on skf_update.status without parsing the human-readable report. The headless_decisions[] array surfaces every auto-resolved gate so non-interactive runs can be audited post-hoc.",
6
+ "$defs": {
7
+ "skf-envelope": {
8
+ "description": "The shared emitter's settings for this workflow, read by skf-emit-result-envelope.py: the workflow, the line's prefix, the wrapper, the status a halt carries and the result file stem. Nothing in the schema references this entry, so it constrains no envelope.",
9
+ "const": {
10
+ "workflow": "skf-update-skill",
11
+ "prefix": "SKF_UPDATE_RESULT_JSON",
12
+ "wrapper": "skf_update",
13
+ "halt_status": "blocked",
14
+ "result_file": "update-skill-result"
15
+ }
16
+ }
17
+ },
6
18
  "type": "object",
7
19
  "additionalProperties": false,
8
20
  "required": ["skf_update"],
@@ -38,7 +50,7 @@
38
50
  "halted-for-concurrent-run",
39
51
  "blocked"
40
52
  ],
41
- "description": "Single-field outcome for pipeline branching. 'success' when the run completed and wrote the updated artifacts. 'no-changes' when detect-changes found nothing to update. 'detect-only' when the workflow was invoked with --detect-only and exited after step 2 without modifying any artifact. 'dry-run' when the workflow was invoked with --dry-run and exited after step 3 (re-extract) without merging or writing — the envelope describes what merge+write WOULD have done. Each 'halted-for-*' value corresponds to a documented halt in the stage prose (workspace-drift from re-extract.md §0.a, brief-refinement from detect-changes.md §1c [U] / §2.2 [B], audit from §2.2 [A], remediation-path from re-extract.md §0a, manual-mismatch from write.md §1, write-failure for any §5b/§6 failure, concurrent-run from init.md §1b's PID-file collision check). 'blocked' is the catch-all for halts that don't map to a documented status code. NOTE: detect-only and dry-run are successful exits — pipelines treating non-success as failure must include them in the success set."
53
+ "description": "Single-field outcome for pipeline branching. 'success' when the run completed and wrote the updated artifacts. 'no-changes' when detect-changes found nothing to update. 'detect-only' when the workflow was invoked with --detect-only and exited after step 2 without modifying any artifact. 'dry-run' when the workflow was invoked with --dry-run and exited after step 3 (re-extract) without merging or writing: the envelope describes what merge+write WOULD have done. Each 'halted-for-*' value corresponds to a documented halt in the stage prose (workspace-drift from gap-driven.md §3, brief-refinement from detect-changes.md §1c [U] / §2.2 [B], audit from §2.2 [A], remediation-path from gap-driven.md §4a, manual-mismatch from write.md §1, after write.md §6's provenance fixes and after write.md §7's skill-check edits (all error.phase 'write:verify-manual-integrity'), from merge.md §6b's check of the merged SKILL.md before it is published (error.phase 'merge:verify-manual-integrity') and from a headless merge that meets a [MANUAL] conflict (error.phase 'merge:conflict-resolution'), write-failure for a merge.md §6b version-folder or SKILL.md write failure (among them error.phase 'merge:new-version-folder' when the version folder already exists or the next version cannot be computed), a failed write in write.md §2 to §5 (error.phase 'write:artifact-write') and a write.md §8/§8a active-link failure, concurrent-run when init.md §1b's acquire finds another run's fresh run lock (error.phase 'init:concurrency-guard'), or when this run no longer holds its lock at the renewal before merge.md §6b or write.md §2 writes (error.phase 'merge:run-lock' or 'write:run-lock'; error.reason 'run-lock-lost: ...' when the lock lapsed while the run waited). error.reason names the run that holds a lock, never a PID). 'blocked' is the catch-all for halts that don't map to a documented status code, among them a headless run given no skill name (error.phase 'init:skill-name', error.reason starting 'input-missing'), a stack skill (error.phase 'init:stack-skill-guard'), init.md §6b (error.phase 'init:source-tree') when no commit to read could be obtained, a helper that failed (each its own '<step>:<section>' phase), and a private source tree that disappeared mid-run (error.phase '<step>:source-tree-missing'). A halt after merge.md §6b's first write, until write.md §10 closes the rollback window, first undoes it: a gap-driven repair's package is restored from the snapshot it took, and a new version's folders are removed, unless the active link already names the new version, which the halt keeps. write.md §8 points the active link at the new version only after §6 and §7, the last checks that can halt, so a [MANUAL] halt never leaves a live version behind. NOTE: detect-only and dry-run are successful exits: pipelines treating non-success as failure must include them in the success set."
42
54
  },
43
55
  "skill_name": {
44
56
  "type": "string",
@@ -48,7 +60,7 @@
48
60
  "version": {
49
61
  "type": "string",
50
62
  "minLength": 1,
51
- "description": "Version written this run. In gap-driven mode this equals previous_version (gap-driven runs do not bump). In normal mode this is either the detected source version or an incremented patch."
63
+ "description": "Version written this run. In gap-driven mode this equals previous_version (gap-driven runs do not bump). In normal mode this is either the detected source version or an incremented patch, and names the new version folder the run created beside the previous one."
52
64
  },
53
65
  "previous_version": {
54
66
  "type": "string",
@@ -80,9 +92,11 @@
80
92
  "type": "string",
81
93
  "enum": [
82
94
  "init.update-confirmation",
95
+ "init.degraded-rebuild",
83
96
  "detect-changes.promoted-doc-prompt",
84
97
  "detect-changes.scope-expansion",
85
98
  "detect-changes.deletion-ratio",
99
+ "gap-driven.rescope",
86
100
  "merge.clean-merge-gate"
87
101
  ],
88
102
  "description": "Identifier for the gate. Matches the labels in stage prose so post-hoc audits can grep both directions."
@@ -95,7 +109,7 @@
95
109
  "taken_action": {
96
110
  "type": "string",
97
111
  "minLength": 1,
98
- "description": "The action actually taken. In headless mode this almost always equals default_action — the field exists so future user-overrides via flags (e.g. --orphan-action style) can differ from defaults."
112
+ "description": "The action actually taken. It differs from default_action where headless resolves a gate its own way: 'D' at init.degraded-rebuild under --allow-degraded, 'R' at gap-driven.rescope when gap-driven.md's rule R1 rescopes the export (one entry per gap, evidence.gap_id), and 'deferred-headless' at detect-changes.promoted-doc-prompt and detect-changes.scope-expansion, where a headless run decides nothing and leaves the path, recorded in the brief's scope.amendments[] as deferred-headless, for the next interactive run. One entry per path at those two gates (evidence.path)."
99
113
  },
100
114
  "reason": {
101
115
  "type": "string",
@@ -114,7 +128,7 @@
114
128
  "warnings": {
115
129
  "type": "array",
116
130
  "items": { "type": "string" },
117
- "description": "Non-fatal anomalies surfaced during the run. May include workspace_drift_overridden, scope_reconciliation_post entries, qmd indexing failures, etc. Empty when none."
131
+ "description": "Non-fatal anomalies surfaced during the run. May include workspace_drift_overridden, scope_reconciliation_post entries, qmd indexing failures, source-tree:, source-not-fetched, source-version-lower, file-diff-unavailable, no-baseline-time, moved-check-skipped and unknown-language (detect-changes.md §2.1 Category A), workspace-clone-not-updated, target-ref-not-recorded, source-tree-not-removed, run-lock-replaced (init.md §1b took over a stale run lock) and run-lock-not-released entries, unconsumed-test-report (init.md §4b: a failing test report newer than the skill that this normal run did not apply), interrupted-run-cleaned and interrupted-run-not-cleaned (init.md §1b undid what an update whose stale lock it replaced had written), proposed-amendment: entries (a --detect-only or --dry-run run's skill brief decisions, not written), doc-fetch-failed, doc-not-hashed and doc-drift-not-checked (a docs-only skill's documents), rollback-incomplete (a halt could not undo all of this run's writes), run-state-not-finished, customization_resolver_unavailable, test-report: entries (what the test report helpers could not read, and test-report: not routed: for each gap a gap-driven run does not repair), etc. Empty when none."
118
132
  },
119
133
  "error": {
120
134
  "oneOf": [