bmad-module-skill-forge 2.2.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (435) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/README.md +49 -49
  3. package/docs/404.md +10 -8
  4. package/docs/_data/pinned.yaml +22 -13
  5. package/docs/_internal/STABILITY.md +58 -35
  6. package/docs/agents.md +39 -53
  7. package/docs/architecture.md +65 -51
  8. package/docs/bmad-synergy.md +53 -51
  9. package/docs/campaign.md +127 -75
  10. package/docs/concepts.md +34 -28
  11. package/docs/examples.md +70 -68
  12. package/docs/forge-auto.md +34 -31
  13. package/docs/getting-started.md +118 -57
  14. package/docs/how-it-works.md +25 -21
  15. package/docs/index.md +15 -15
  16. package/docs/skill-model.md +70 -59
  17. package/docs/troubleshooting.md +135 -18
  18. package/docs/verifying-a-skill.md +83 -57
  19. package/docs/why-skf.md +24 -22
  20. package/docs/workflows.md +274 -110
  21. package/package.json +18 -10
  22. package/src/forger/preferences.yaml +8 -1
  23. package/src/knowledge/agentskills-spec.md +2 -0
  24. package/src/knowledge/ccc-bridge.md +40 -24
  25. package/src/knowledge/confidence-tiers.md +9 -5
  26. package/src/knowledge/overview.md +3 -3
  27. package/src/knowledge/progressive-capability.md +8 -8
  28. package/src/knowledge/provenance-tracking.md +9 -5
  29. package/src/knowledge/qmd-registry.md +2 -2
  30. package/src/knowledge/skf-knowledge-index.csv +2 -2
  31. package/src/knowledge/skill-lifecycle.md +18 -11
  32. package/src/knowledge/split-body-strategy.md +0 -3
  33. package/src/knowledge/tool-resolution.md +4 -2
  34. package/src/knowledge/version-paths.md +101 -15
  35. package/src/module-help.csv +3 -3
  36. package/src/module.yaml +10 -0
  37. package/src/shared/data/ast-grep-recipes.yaml +608 -0
  38. package/src/shared/data/ide-context-files.json +30 -0
  39. package/src/shared/health-check.md +32 -12
  40. package/src/shared/references/description-guard-protocol.md +12 -9
  41. package/src/shared/references/feasibility-report-schema.md +19 -13
  42. package/src/shared/references/headless-gate-convention.md +55 -3
  43. package/src/shared/references/output-contract-schema.md +19 -8
  44. package/src/shared/references/pipeline-contracts.md +94 -29
  45. package/src/shared/references/tessl-review.md +77 -0
  46. package/src/shared/scripts/schemas/skf-analyze-result-envelope.v1.json +194 -0
  47. package/src/shared/scripts/schemas/skf-audit-result-envelope.v1.json +192 -0
  48. package/src/shared/scripts/schemas/skf-brief-result-envelope.v1.json +32 -4
  49. package/src/shared/scripts/schemas/skf-campaign-result-envelope.v1.json +174 -0
  50. package/src/shared/scripts/schemas/skf-create-skill-result-envelope.v1.json +284 -0
  51. package/src/shared/scripts/schemas/skf-drop-skill-result-envelope.v1.json +164 -0
  52. package/src/shared/scripts/schemas/skf-export-result-envelope.v1.json +160 -0
  53. package/src/shared/scripts/schemas/skf-quick-skill-result-envelope.v1.json +261 -0
  54. package/src/shared/scripts/schemas/skf-refine-architecture-result-envelope.v1.json +192 -0
  55. package/src/shared/scripts/schemas/skf-rename-skill-result-envelope.v1.json +179 -0
  56. package/src/shared/scripts/schemas/skf-setup-result-envelope.v1.json +27 -11
  57. package/src/shared/scripts/schemas/skf-stack-result-envelope.v1.json +176 -0
  58. package/src/shared/scripts/schemas/skf-test-result-envelope.v1.json +173 -0
  59. package/src/shared/scripts/schemas/skf-update-result-envelope.v1.json +19 -5
  60. package/src/shared/scripts/schemas/skf-verify-stack-result-envelope.v1.json +180 -0
  61. package/src/shared/scripts/schemas/skill-brief.v1.json +34 -0
  62. package/src/shared/scripts/schemas/workspace-detection.v1.json +1 -1
  63. package/src/shared/scripts/skf-atomic-write.py +30 -14
  64. package/src/shared/scripts/skf-build-change-manifest.py +2203 -24
  65. package/src/shared/scripts/skf-ccc-git-hygiene.py +532 -0
  66. package/src/shared/scripts/skf-check-unit-records.py +184 -0
  67. package/src/shared/scripts/skf-check-workspace-drift.py +538 -9
  68. package/src/shared/scripts/skf-classify-changed-files.py +694 -0
  69. package/src/shared/scripts/skf-comention-pairs.py +1333 -123
  70. package/src/shared/scripts/skf-compare-file-hashes.py +1 -1
  71. package/src/shared/scripts/skf-count-imports.py +1867 -0
  72. package/src/shared/scripts/skf-count-tokens.py +1 -1
  73. package/src/shared/scripts/skf-derive-assembly-shape.py +3 -2
  74. package/src/shared/scripts/skf-description-guard.py +99 -11
  75. package/src/shared/scripts/skf-detect-docs.py +694 -2
  76. package/src/shared/scripts/skf-detect-language.py +486 -107
  77. package/src/shared/scripts/skf-detect-registry.py +887 -0
  78. package/src/shared/scripts/skf-detect-scripts-assets.py +1 -1
  79. package/src/shared/scripts/skf-detect-tools.py +209 -27
  80. package/src/shared/scripts/skf-detect-workspaces.py +506 -30
  81. package/src/shared/scripts/skf-disqualify-candidates.py +821 -182
  82. package/src/shared/scripts/skf-emit-brief-result-envelope.py +69 -191
  83. package/src/shared/scripts/skf-emit-result-envelope.py +1604 -106
  84. package/src/shared/scripts/skf-enumerate-stack-skills.py +986 -117
  85. package/src/shared/scripts/skf-extract-public-api.py +4084 -85
  86. package/src/shared/scripts/skf-extraction-inventory.py +746 -0
  87. package/src/shared/scripts/skf-extraction-snapshot.py +539 -0
  88. package/src/shared/scripts/skf-fetch-temporal.py +674 -0
  89. package/src/shared/scripts/skf-find-cycles.py +97 -29
  90. package/src/shared/scripts/skf-find-test-report.py +476 -0
  91. package/src/shared/scripts/skf-forge-tier-rw.py +444 -203
  92. package/src/shared/scripts/skf-github-fetch.py +365 -0
  93. package/src/shared/scripts/skf-github-probe.py +661 -0
  94. package/src/shared/scripts/skf-hash-content.py +166 -12
  95. package/src/shared/scripts/skf-language-corpora.py +1 -1
  96. package/src/shared/scripts/skf-load-provenance.py +159 -27
  97. package/src/shared/scripts/skf-manifest-ops.py +1 -1
  98. package/src/shared/scripts/skf-merge-ccc-exclusions.py +2307 -223
  99. package/src/shared/scripts/skf-merge-doc-urls.py +1 -1
  100. package/src/shared/scripts/skf-names-present.py +221 -0
  101. package/src/shared/scripts/skf-pair-intersect.py +119 -28
  102. package/src/shared/scripts/skf-parse-gaps.py +1384 -0
  103. package/src/shared/scripts/skf-preapply.py +1 -1
  104. package/src/shared/scripts/skf-preflight.py +161 -27
  105. package/src/shared/scripts/skf-promote-staged.py +430 -0
  106. package/src/shared/scripts/skf-provenance-gap-dispatch.py +39 -7
  107. package/src/shared/scripts/skf-qmd-classify-collections.py +229 -45
  108. package/src/shared/scripts/skf-quick-batch.py +774 -0
  109. package/src/shared/scripts/skf-rebuild-managed-sections.py +972 -88
  110. package/src/shared/scripts/skf-recommend-scope-type.py +323 -156
  111. package/src/shared/scripts/skf-render-metadata-stats.py +156 -12
  112. package/src/shared/scripts/skf-render-quick-metadata.py +132 -28
  113. package/src/shared/scripts/skf-render-stack-metadata.py +976 -0
  114. package/src/shared/scripts/skf-resolve-authoritative-files.py +128 -13
  115. package/src/shared/scripts/skf-resolve-package.py +523 -106
  116. package/src/shared/scripts/skf-rewrite-skill-name.py +433 -47
  117. package/src/shared/scripts/skf-run-lock.py +577 -0
  118. package/src/shared/scripts/skf-scan-manifests.py +998 -57
  119. package/src/shared/scripts/skf-scan-skill-md-structure.py +1341 -37
  120. package/src/shared/scripts/skf-severity-classify.py +712 -108
  121. package/src/shared/scripts/skf-shape-detect.py +298 -204
  122. package/src/shared/scripts/skf-shard-body.py +9 -8
  123. package/src/shared/scripts/skf-skill-inventory.py +2412 -89
  124. package/src/shared/scripts/skf-skills-module.py +472 -0
  125. package/src/shared/scripts/skf-source-tree.py +1796 -0
  126. package/src/shared/scripts/skf-structural-diff.py +670 -119
  127. package/src/shared/scripts/skf-tessl-review.py +706 -0
  128. package/src/shared/scripts/skf-update-active-symlink.py +5 -5
  129. package/src/shared/scripts/skf-update-run-state.py +624 -0
  130. package/src/shared/scripts/skf-validate-brief-inputs.py +92 -29
  131. package/src/shared/scripts/skf-validate-brief-schema.py +4 -1
  132. package/src/shared/scripts/skf-validate-feasibility-report.py +577 -66
  133. package/src/shared/scripts/skf-validate-frontmatter.py +103 -26
  134. package/src/shared/scripts/skf-validate-output.py +712 -64
  135. package/src/shared/scripts/skf-validate-pins.py +1 -1
  136. package/src/shared/scripts/skf-verify-no-trace.py +116 -10
  137. package/src/shared/scripts/skf-verify-provenance-completeness.py +2919 -54
  138. package/src/shared/scripts/skf-write-skill-brief.py +367 -19
  139. package/src/shared/tool-requirements.yaml +201 -0
  140. package/src/skf-analyze-source/SKILL.md +41 -36
  141. package/src/skf-analyze-source/assets/skill-brief-schema.md +7 -8
  142. package/src/skf-analyze-source/customize.toml +36 -24
  143. package/src/skf-analyze-source/references/auto-docs-only.md +58 -20
  144. package/src/skf-analyze-source/references/continue.md +2 -13
  145. package/src/skf-analyze-source/references/discover-additional-source.md +147 -0
  146. package/src/skf-analyze-source/references/generate-briefs.md +121 -55
  147. package/src/skf-analyze-source/references/headless-contract.md +42 -15
  148. package/src/skf-analyze-source/references/identify-units.md +96 -110
  149. package/src/skf-analyze-source/references/init.md +73 -71
  150. package/src/skf-analyze-source/references/map-and-detect.md +123 -105
  151. package/src/skf-analyze-source/references/map-unit-exports.md +68 -0
  152. package/src/skf-analyze-source/references/recommend.md +51 -70
  153. package/src/skf-analyze-source/references/scan-project.md +60 -84
  154. package/src/skf-analyze-source/references/scan-root.md +39 -0
  155. package/src/skf-analyze-source/references/step-auto-scope-coexistence.md +47 -0
  156. package/src/skf-analyze-source/references/step-auto-scope-corpora.md +53 -0
  157. package/src/skf-analyze-source/references/step-auto-scope-split.md +91 -0
  158. package/src/skf-analyze-source/references/step-auto-scope.md +208 -293
  159. package/src/skf-analyze-source/references/step-shape-detect.md +14 -12
  160. package/src/skf-analyze-source/references/unit-detection-heuristics.md +37 -42
  161. package/src/skf-audit-skill/SKILL.md +43 -51
  162. package/src/skf-audit-skill/assets/drift-report-template.md +27 -3
  163. package/src/skf-audit-skill/customize.toml +41 -20
  164. package/src/skf-audit-skill/references/constituent-freshness.md +91 -0
  165. package/src/skf-audit-skill/references/doc-drift.md +141 -0
  166. package/src/skf-audit-skill/references/headless-contract.md +29 -0
  167. package/src/skf-audit-skill/references/init.md +148 -210
  168. package/src/skf-audit-skill/references/re-index.md +96 -108
  169. package/src/skf-audit-skill/references/report.md +96 -33
  170. package/src/skf-audit-skill/references/semantic-diff.md +27 -18
  171. package/src/skf-audit-skill/references/severity-classify.md +79 -65
  172. package/src/skf-audit-skill/references/severity-rules.md +15 -6
  173. package/src/skf-audit-skill/references/structural-diff.md +75 -90
  174. package/src/skf-audit-skill/references/upstream-checkout.md +77 -0
  175. package/src/skf-audit-skill/scripts/render-drift-tables.py +685 -0
  176. package/src/skf-brief-skill/SKILL.md +36 -25
  177. package/src/skf-brief-skill/assets/description-voice-examples.md +1 -1
  178. package/src/skf-brief-skill/assets/scope-templates.md +17 -24
  179. package/src/skf-brief-skill/assets/skill-brief-schema.md +29 -15
  180. package/src/skf-brief-skill/customize.toml +48 -20
  181. package/src/skf-brief-skill/references/analyze-target.md +142 -125
  182. package/src/skf-brief-skill/references/confirm-brief.md +10 -8
  183. package/src/skf-brief-skill/references/draft-checkpoint.md +36 -17
  184. package/src/skf-brief-skill/references/gather-intent-ratify.md +68 -0
  185. package/src/skf-brief-skill/references/gather-intent.md +87 -182
  186. package/src/skf-brief-skill/references/headless-args.md +84 -16
  187. package/src/skf-brief-skill/references/health-check.md +1 -1
  188. package/src/skf-brief-skill/references/invocation-contract.md +18 -13
  189. package/src/skf-brief-skill/references/portfolio-similarity-check.md +1 -1
  190. package/src/skf-brief-skill/references/qmd-collection-registration.md +7 -10
  191. package/src/skf-brief-skill/references/scope-definition.md +123 -47
  192. package/src/skf-brief-skill/references/step-auto-brief.md +24 -80
  193. package/src/skf-brief-skill/references/step-auto-validate.md +20 -121
  194. package/src/skf-brief-skill/references/version-resolution.md +3 -2
  195. package/src/skf-brief-skill/references/write-brief.md +66 -57
  196. package/src/skf-campaign/SKILL.md +31 -34
  197. package/src/skf-campaign/assets/campaign-state-schema.json +25 -4
  198. package/src/skf-campaign/customize.toml +47 -16
  199. package/src/skf-campaign/references/campaign-contracts.md +39 -29
  200. package/src/skf-campaign/references/campaign-directive-spec.md +4 -2
  201. package/src/skf-campaign/references/health-check.md +7 -16
  202. package/src/skf-campaign/references/step-01-setup.md +46 -84
  203. package/src/skf-campaign/references/step-02-strategy.md +31 -30
  204. package/src/skf-campaign/references/step-03-pins.md +26 -18
  205. package/src/skf-campaign/references/step-04-provenance.md +24 -23
  206. package/src/skf-campaign/references/step-05-skill-loop.md +67 -48
  207. package/src/skf-campaign/references/step-06-batch.md +41 -34
  208. package/src/skf-campaign/references/step-07-capstone.md +40 -25
  209. package/src/skf-campaign/references/step-08-verify.md +28 -29
  210. package/src/skf-campaign/references/step-09-refine.md +29 -30
  211. package/src/skf-campaign/references/step-10-export.md +48 -36
  212. package/src/skf-campaign/references/step-11-maintenance.md +31 -34
  213. package/src/skf-campaign/references/step-resume.md +37 -68
  214. package/src/skf-campaign/scripts/campaign-deps.py +57 -18
  215. package/src/skf-campaign/scripts/campaign-parse-manifest.py +361 -54
  216. package/src/skf-campaign/scripts/campaign-provenance.py +96 -53
  217. package/src/skf-campaign/scripts/campaign-quality-gate.py +592 -0
  218. package/src/skf-campaign/scripts/campaign-render-batch.py +257 -49
  219. package/src/skf-campaign/scripts/campaign-render-kickoff.py +343 -50
  220. package/src/skf-campaign/scripts/campaign-report.py +204 -37
  221. package/src/skf-campaign/scripts/campaign-state.py +1128 -0
  222. package/src/skf-campaign/scripts/campaign-status.py +10 -74
  223. package/src/skf-campaign/scripts/campaign-validate-pins.py +30 -3
  224. package/src/skf-campaign/scripts/campaign-validate-state.py +34 -4
  225. package/src/skf-campaign/templates/campaign-brief-template.yaml +4 -5
  226. package/src/skf-campaign/templates/campaign-report-template.md +5 -1
  227. package/src/skf-campaign/templates/kickoff-template.md +0 -14
  228. package/src/skf-create-skill/SKILL.md +27 -20
  229. package/src/skf-create-skill/assets/compile-assembly-rules.md +6 -5
  230. package/src/skf-create-skill/assets/skill-sections.md +15 -5
  231. package/src/skf-create-skill/customize.toml +20 -8
  232. package/src/skf-create-skill/references/authoritative-files-protocol.md +41 -42
  233. package/src/skf-create-skill/references/batch-mode.md +81 -0
  234. package/src/skf-create-skill/references/ccc-index-check.md +27 -0
  235. package/src/skf-create-skill/references/compile.md +107 -29
  236. package/src/skf-create-skill/references/component-extraction.md +113 -91
  237. package/src/skf-create-skill/references/enrich.md +41 -23
  238. package/src/skf-create-skill/references/entry-points-by-hand.md +20 -0
  239. package/src/skf-create-skill/references/extract.md +200 -161
  240. package/src/skf-create-skill/references/extraction-patterns-by-hand.md +141 -0
  241. package/src/skf-create-skill/references/extraction-patterns-tracing.md +2 -2
  242. package/src/skf-create-skill/references/extraction-patterns.md +584 -196
  243. package/src/skf-create-skill/references/generate-artifacts.md +145 -93
  244. package/src/skf-create-skill/references/health-check.md +1 -1
  245. package/src/skf-create-skill/references/load-brief.md +53 -36
  246. package/src/skf-create-skill/references/relabel-rule.md +12 -0
  247. package/src/skf-create-skill/references/report.md +28 -59
  248. package/src/skf-create-skill/references/source-resolution-protocols.md +49 -155
  249. package/src/skf-create-skill/references/step-auto-shard.md +20 -93
  250. package/src/skf-create-skill/references/step-doc-rot.md +44 -60
  251. package/src/skf-create-skill/references/step-doc-sources.md +28 -19
  252. package/src/skf-create-skill/references/sub/ccc-discover.md +18 -7
  253. package/src/skf-create-skill/references/sub/fetch-docs.md +106 -59
  254. package/src/skf-create-skill/references/sub/fetch-temporal.md +53 -166
  255. package/src/skf-create-skill/references/tier-degradation-rules.md +18 -9
  256. package/src/skf-create-skill/references/validate.md +173 -99
  257. package/src/skf-create-skill/scripts/scan-doc-rot.py +232 -99
  258. package/src/skf-create-stack-skill/SKILL.md +29 -56
  259. package/src/skf-create-stack-skill/assets/metadata-contract.md +51 -0
  260. package/src/skf-create-stack-skill/assets/provenance-map-schema.md +15 -15
  261. package/src/skf-create-stack-skill/assets/stack-skill-template.md +23 -57
  262. package/src/skf-create-stack-skill/customize.toml +23 -12
  263. package/src/skf-create-stack-skill/references/compile-stack.md +57 -66
  264. package/src/skf-create-stack-skill/references/compose-mode-rules.md +24 -44
  265. package/src/skf-create-stack-skill/references/detect-integrations.md +92 -95
  266. package/src/skf-create-stack-skill/references/detect-manifests.md +46 -71
  267. package/src/skf-create-stack-skill/references/generate-output.md +138 -128
  268. package/src/skf-create-stack-skill/references/init.md +90 -32
  269. package/src/skf-create-stack-skill/references/integration-patterns.md +1 -17
  270. package/src/skf-create-stack-skill/references/invocation-contract.md +34 -0
  271. package/src/skf-create-stack-skill/references/manifest-patterns.md +32 -20
  272. package/src/skf-create-stack-skill/references/parallel-extract.md +112 -38
  273. package/src/skf-create-stack-skill/references/rank-and-confirm.md +57 -75
  274. package/src/skf-create-stack-skill/references/report.md +39 -33
  275. package/src/skf-create-stack-skill/references/validate.md +20 -39
  276. package/src/skf-drop-skill/SKILL.md +28 -51
  277. package/src/skf-drop-skill/customize.toml +44 -30
  278. package/src/skf-drop-skill/references/execute.md +79 -146
  279. package/src/skf-drop-skill/references/invocation-contract.md +64 -0
  280. package/src/skf-drop-skill/references/report.md +46 -30
  281. package/src/skf-drop-skill/references/select.md +118 -124
  282. package/src/skf-drop-skill/scripts/dir-sizes.py +54 -26
  283. package/src/skf-drop-skill/scripts/drop-roster.py +322 -0
  284. package/src/skf-export-skill/SKILL.md +40 -62
  285. package/src/skf-export-skill/assets/managed-section-format.md +14 -50
  286. package/src/skf-export-skill/assets/snippet-format.md +3 -1
  287. package/src/skf-export-skill/customize.toml +42 -13
  288. package/src/skf-export-skill/references/generate-snippet.md +54 -46
  289. package/src/skf-export-skill/references/health-check.md +2 -0
  290. package/src/skf-export-skill/references/invocation-contract.md +15 -0
  291. package/src/skf-export-skill/references/load-skill.md +88 -62
  292. package/src/skf-export-skill/references/manifest-rebuild.md +9 -10
  293. package/src/skf-export-skill/references/multi-skill-mode.md +4 -4
  294. package/src/skf-export-skill/references/orphan-context-detection.md +13 -5
  295. package/src/skf-export-skill/references/orphan-row-detection.md +31 -22
  296. package/src/skf-export-skill/references/package.md +15 -73
  297. package/src/skf-export-skill/references/preflight-snippet-root-probe.md +51 -70
  298. package/src/skf-export-skill/references/result-envelope.md +31 -16
  299. package/src/skf-export-skill/references/summary.md +41 -17
  300. package/src/skf-export-skill/references/token-report.md +4 -12
  301. package/src/skf-export-skill/references/update-context.md +118 -237
  302. package/src/skf-forger/SKILL.md +61 -37
  303. package/src/skf-forger/bmad-skill-manifest.yaml +4 -1
  304. package/src/skf-forger/customize.toml +43 -0
  305. package/src/skf-forger/references/pipeline-mode.md +73 -18
  306. package/src/skf-forger/scripts/forge-status.py +299 -0
  307. package/src/skf-forger/scripts/parse-pipeline.py +322 -54
  308. package/src/skf-forger/scripts/pipeline-gate.py +428 -0
  309. package/src/skf-forger/scripts/pipeline-journal.py +1052 -0
  310. package/src/skf-quick-skill/SKILL.md +54 -53
  311. package/src/skf-quick-skill/assets/skill-template.md +4 -2
  312. package/src/skf-quick-skill/customize.toml +51 -20
  313. package/src/skf-quick-skill/references/batch-mode.md +74 -21
  314. package/src/skf-quick-skill/references/compile.md +30 -31
  315. package/src/skf-quick-skill/references/ecosystem-check.md +7 -57
  316. package/src/skf-quick-skill/references/finalize.md +69 -18
  317. package/src/skf-quick-skill/references/halt-contract.md +41 -29
  318. package/src/skf-quick-skill/references/health-check.md +5 -3
  319. package/src/skf-quick-skill/references/quick-extract.md +114 -45
  320. package/src/skf-quick-skill/references/registry-resolution.md +9 -64
  321. package/src/skf-quick-skill/references/resolve-target.md +116 -66
  322. package/src/skf-quick-skill/references/write-and-validate.md +79 -40
  323. package/src/skf-refine-architecture/SKILL.md +43 -53
  324. package/src/skf-refine-architecture/customize.toml +49 -20
  325. package/src/skf-refine-architecture/references/compile.md +97 -54
  326. package/src/skf-refine-architecture/references/exit-codes.md +30 -0
  327. package/src/skf-refine-architecture/references/finding-storage.md +21 -0
  328. package/src/skf-refine-architecture/references/gap-analysis.md +101 -38
  329. package/src/skf-refine-architecture/references/improvements.md +14 -20
  330. package/src/skf-refine-architecture/references/init.md +98 -57
  331. package/src/skf-refine-architecture/references/issue-detection.md +32 -39
  332. package/src/skf-refine-architecture/references/refinement-rules.md +37 -48
  333. package/src/skf-refine-architecture/references/report.md +65 -54
  334. package/src/skf-refine-architecture/scripts/skf-check-preservation.py +1619 -0
  335. package/src/skf-rename-skill/SKILL.md +19 -54
  336. package/src/skf-rename-skill/customize.toml +32 -26
  337. package/src/skf-rename-skill/references/execute.md +230 -184
  338. package/src/skf-rename-skill/references/exit-codes.md +7 -7
  339. package/src/skf-rename-skill/references/health-check.md +1 -7
  340. package/src/skf-rename-skill/references/invocation-contract.md +25 -0
  341. package/src/skf-rename-skill/references/report.md +63 -52
  342. package/src/skf-rename-skill/references/select.md +197 -115
  343. package/src/skf-rename-skill/scripts/skf-validate-rename-name.py +161 -21
  344. package/src/skf-setup/SKILL.md +26 -26
  345. package/src/skf-setup/customize.toml +14 -10
  346. package/src/skf-setup/references/auto-index.md +50 -63
  347. package/src/skf-setup/references/ccc-index.md +29 -90
  348. package/src/skf-setup/references/detect-and-tier.md +58 -67
  349. package/src/skf-setup/references/health-check.md +2 -0
  350. package/src/skf-setup/references/invocation-contract.md +14 -0
  351. package/src/skf-setup/references/report.md +43 -166
  352. package/src/skf-setup/references/tier-rules.md +5 -5
  353. package/src/skf-setup/references/write-config.md +34 -57
  354. package/src/skf-test-skill/SKILL.md +17 -57
  355. package/src/skf-test-skill/assets/output-section-formats.md +33 -34
  356. package/src/skf-test-skill/customize.toml +27 -13
  357. package/src/skf-test-skill/references/coherence-check.md +134 -62
  358. package/src/skf-test-skill/references/coverage-check-tiers.md +35 -0
  359. package/src/skf-test-skill/references/coverage-check.md +217 -254
  360. package/src/skf-test-skill/references/detect-mode.md +5 -5
  361. package/src/skf-test-skill/references/external-validators.md +94 -82
  362. package/src/skf-test-skill/references/health-check.md +6 -7
  363. package/src/skf-test-skill/references/init.md +163 -88
  364. package/src/skf-test-skill/references/invocation-contract.md +66 -0
  365. package/src/skf-test-skill/references/migration-section-rules.md +5 -2
  366. package/src/skf-test-skill/references/report.md +162 -142
  367. package/src/skf-test-skill/references/score.md +80 -107
  368. package/src/skf-test-skill/references/scoring-rules.md +41 -155
  369. package/src/skf-test-skill/references/source-access-protocol.md +19 -92
  370. package/src/skf-test-skill/references/step-hard-gate.md +51 -33
  371. package/src/skf-test-skill/scripts/aggregate-coherence.py +218 -30
  372. package/src/skf-test-skill/scripts/build-result-context.py +287 -0
  373. package/src/skf-test-skill/scripts/check-metadata-coherence.py +37 -4
  374. package/src/skf-test-skill/scripts/combine-external-scores.py +23 -6
  375. package/src/skf-test-skill/scripts/compute-score.py +223 -45
  376. package/src/skf-test-skill/scripts/gap-ledger.py +1381 -0
  377. package/src/skf-test-skill/scripts/hard-gate.py +203 -0
  378. package/src/skf-test-skill/scripts/load-coverage-inputs.py +760 -0
  379. package/src/skf-test-skill/scripts/locate-export-segments.py +835 -0
  380. package/src/skf-test-skill/scripts/reconcile-coverage.py +273 -79
  381. package/src/skf-test-skill/scripts/score-signatures.py +459 -0
  382. package/src/skf-test-skill/scripts/stage-helper-payload.py +148 -0
  383. package/src/skf-test-skill/scripts/validate-inventory.py +311 -16
  384. package/src/skf-test-skill/scripts/verify-declared-numerator.py +127 -52
  385. package/src/skf-test-skill/templates/test-report-template.md +21 -15
  386. package/src/skf-update-skill/SKILL.md +38 -25
  387. package/src/skf-update-skill/customize.toml +27 -12
  388. package/src/skf-update-skill/references/detect-changes.md +233 -222
  389. package/src/skf-update-skill/references/gap-driven.md +336 -0
  390. package/src/skf-update-skill/references/health-check.md +31 -5
  391. package/src/skf-update-skill/references/init.md +250 -84
  392. package/src/skf-update-skill/references/invocation-contract.md +12 -0
  393. package/src/skf-update-skill/references/manual-section-rules.md +6 -23
  394. package/src/skf-update-skill/references/merge.md +180 -47
  395. package/src/skf-update-skill/references/re-extract.md +53 -262
  396. package/src/skf-update-skill/references/report.md +100 -35
  397. package/src/skf-update-skill/references/write.md +331 -149
  398. package/src/skf-update-skill/scripts/skf-new-file-diff.py +29 -7
  399. package/src/skf-verify-stack/SKILL.md +23 -42
  400. package/src/skf-verify-stack/assets/feasibility-report-template.md +11 -5
  401. package/src/skf-verify-stack/customize.toml +55 -22
  402. package/src/skf-verify-stack/references/coverage-patterns.md +17 -8
  403. package/src/skf-verify-stack/references/coverage.md +67 -64
  404. package/src/skf-verify-stack/references/exit-codes.md +21 -8
  405. package/src/skf-verify-stack/references/init.md +107 -62
  406. package/src/skf-verify-stack/references/integration-verification-rules.md +12 -13
  407. package/src/skf-verify-stack/references/integrations.md +106 -65
  408. package/src/skf-verify-stack/references/report.md +59 -42
  409. package/src/skf-verify-stack/references/requirements.md +32 -9
  410. package/src/skf-verify-stack/references/synthesize.md +53 -39
  411. package/src/skf-verify-stack/scripts/skf-coverage-tally.py +398 -52
  412. package/src/skf-verify-stack/scripts/skf-previous-report.py +330 -0
  413. package/src/skf-verify-stack/scripts/skf-report-delta.py +453 -49
  414. package/src/skf-verify-stack/scripts/skf-verdict-rollup.py +240 -27
  415. package/tools/cli/commands/install.js +11 -4
  416. package/tools/cli/commands/status.js +15 -3
  417. package/tools/cli/commands/update.js +11 -4
  418. package/tools/cli/lib/tool-check.js +320 -0
  419. package/tools/cli/lib/version-check.js +22 -9
  420. package/tools/cli/skf-cli.js +4 -1
  421. package/.gitattributes +0 -16
  422. package/.nvmrc +0 -1
  423. package/docs/_internal/RELEASING.md +0 -679
  424. package/release-audits/v1.0.0-launch-audit.md +0 -728
  425. package/src/skf-audit-skill/references/step-doc-drift.md +0 -177
  426. package/src/skf-brief-skill/references/headless-source-authority-detection.md +0 -26
  427. package/src/skf-campaign/manifest.yaml +0 -15
  428. package/src/skf-create-skill/assets/tessl-dismissal-rules.md +0 -106
  429. package/src/skf-create-skill/references/ecosystem-check.md +0 -74
  430. package/src/skf-drop-skill/references/headless-contract.md +0 -18
  431. package/src/skf-update-skill/references/merge-conflict-rules.md +0 -15
  432. package/src/skf-update-skill/references/remote-source-resolution.md +0 -98
  433. package/src/skf-update-skill/references/validate.md +0 -124
  434. package/tools/validate-docs-drift.js +0 -233
  435. package/tools/validate-docs-links.js +0 -665
@@ -1,7 +1,25 @@
1
1
  ---
2
- nextStepFile: 'validate.md'
2
+ nextStepFile: 'write.md'
3
3
  manualSectionRulesFile: 'references/manual-section-rules.md'
4
- mergeConflictRulesFile: 'references/merge-conflict-rules.md'
4
+ # Resolve `{atomicWriteHelper}` by probing `{atomicWriteProbeOrder}` in order
5
+ # (installed SKF module path first, src/ dev-checkout fallback); first
6
+ # existing path wins. HALT if neither resolves when §6b creates a version
7
+ # folder — a folder copied in place instead of staged and renamed would
8
+ # leave a half-copied version behind on any failure.
9
+ atomicWriteProbeOrder:
10
+ - '{project-root}/_bmad/skf/shared/scripts/skf-atomic-write.py'
11
+ - '{project-root}/src/shared/scripts/skf-atomic-write.py'
12
+ # Resolve `{skillInventoryHelper}` to the first existing path when §6b needs
13
+ # the next patch version; HALT if neither resolves: never pick it by hand.
14
+ skillInventoryProbeOrder:
15
+ - '{project-root}/_bmad/skf/shared/scripts/skf-skill-inventory.py'
16
+ - '{project-root}/src/shared/scripts/skf-skill-inventory.py'
17
+ # Resolve `{hashContentHelper}` to the first existing path; HALT if neither
18
+ # exists: §4 amends the [MANUAL] inventory with the user's decisions and §6b
19
+ # verifies the merged SKILL.md against it before anything is published.
20
+ hashContentProbeOrder:
21
+ - '{project-root}/_bmad/skf/shared/scripts/skf-hash-content.py'
22
+ - '{project-root}/src/shared/scripts/skf-hash-content.py'
5
23
  ---
6
24
 
7
25
  <!-- Config: communicate in {communication_language}. -->
@@ -15,26 +33,42 @@ Merge freshly extracted export data into the existing SKILL.md content while pre
15
33
  ## Rules
16
34
 
17
35
  - Focus only on merging extractions into existing skill content
18
- - Never delete or modify [MANUAL] section content
19
- - Write merged SKILL.md directly to disk at section 6b — Claude Code's Edit/Write tools commit on call, so there is no held-in-memory "edit plan" primitive; subsequent steps validate and verify against the on-disk files
20
- - If [MANUAL] conflicts detected: halt and present to user. If clean merge: auto-proceed
36
+ - Never delete or modify [MANUAL] section content without the user's section 4 [R]/[E] decision
37
+ - Write the merged files to disk at section 6b, once §6b has recorded what this run writes (`{runStateHelper}` `begin`), and verify the merged SKILL.md against the [MANUAL] inventory the user approved before it is published: in a staged version folder outside gap-driven mode, in `{run_dir}` in gap-driven mode. Later steps verify the files on disk
38
+ - If [MANUAL] conflicts detected: halt and present to user (headless: HALT, nothing written). If clean merge: auto-proceed
21
39
 
22
40
  ## Steps
23
41
 
42
+ **Halt procedure.** Every HALT in this step names its payload (`status`, `phase`, `path` when it has one, and `reason`), displays its message, and then runs, from `{project-root}`, the halt helper SKILL.md On Activation resolved.
43
+
44
+ ```bash
45
+ uv run {runStateHelper} halt --run-dir "{run_dir}" \
46
+ [--tree "{source_tree}"] \
47
+ [--lock "{forge_data_folder}/{skill_name}/.skf-update.lock" --owner "{lock_owner}"] \
48
+ [--emit] <<'SKF_JSON'
49
+ {"status": "<status>", "phase": "<phase>", "path": "<path; leave the key out when the halt names none>", "reason": "<reason>", "skill_name": "{skill_name}", "version": "<the metadata.json version>", "previous_version": "<the same>", "update_mode": "<normal, gap-driven or degraded>"}
50
+ SKF_JSON
51
+ ```
52
+
53
+ Pass `--tree` when init.md §6b bound `{source_tree}`, always `--lock` and `--owner`, and `--emit` in `{headless_mode}`. Once §6b has run `begin`, the helper first undoes what this run wrote: in gap-driven mode it restores the package, the version's provenance map and evidence report, and the skill brief from the snapshot `begin` took; in every other mode it removes the version folders `begin` recorded (never one the `active` link names). Then it removes the private source tree, releases the run lock (never one another run holds) and, with `--emit`, prints the halt's `SKF_UPDATE_RESULT_JSON:` line through the shared emitter, which adds the decisions recorded so far, the `error` object and a warning for each step the helper could not finish (`rollback-incomplete`, `source-tree-not-removed`, `run-lock-not-released`); it never stops on a result. Tell the user in one line what it restored and removed, and name each path its `failed[]` lists for the user to restore or delete by hand. The emitter adds `files_written: []`: after the rollback nothing this run wrote stands. Write each payload value as a JSON string: escape `"` and `\`, and write every path with `/`. Display the line it prints verbatim. When it exits 1 and its message names the payload, fix the payload once and run it again, which redoes nothing already done; when it still fails or prints no line, display the halt message alone. An interactive HALT displays its message and emits nothing. A HALT that names no payload (a helper the frontmatter says to HALT without, resolving to no path) takes `status: "blocked"`, `phase: "merge:<the helper's file name>"` and `reason: "<the helper's file name> is missing; re-install SKF"`.
54
+
55
+ The halt leaves `{run_dir}` in place.
56
+
24
57
  ### 1. Load Merge Rules
25
58
 
26
- Load {manualSectionRulesFile} for [MANUAL] detection and preservation patterns.
27
- Load {mergeConflictRulesFile} for the conflict-resolution strategy table (the change-category actions and priority order live in §3 below).
59
+ Load {manualSectionRulesFile} for [MANUAL] detection and preservation patterns. The change-category actions and their priority order are in §3 below, and the conflict handling in §4.
28
60
 
29
61
  ### 2. Extract [MANUAL] Blocks
30
62
 
31
- From the [MANUAL] inventory captured in step 01:
63
+ From the [MANUAL] inventory captured in step 1:
32
64
  - Extract every `<!-- [MANUAL:section-name] -->` ... `<!-- [/MANUAL:section-name] -->` block
33
65
  - Map each block to its parent section heading
34
66
  - Store blocks in a preservation map keyed by section-name
35
67
 
36
68
  ### 3. Apply Merge by Priority Order
37
69
 
70
+ Read this step's inputs from disk, never from memory: the change manifest from `{run_dir}/change-manifest.json` (step 2, or gap-driven.md §1 in gap-driven mode), the extraction or verification records from `{run_dir}/reextract-records.json` (step 3, or gap-driven.md §4), and the documents step 2 §1b promoted from `{run_dir}/promoted-docs.json` when it wrote that file. A compacted context still merges what those steps found.
71
+
38
72
  Apply merge in the following priority order:
39
73
 
40
74
  **Priority 1 — Process DELETED exports:**
@@ -42,10 +76,11 @@ Apply merge in the following priority order:
42
76
  - Check if deleted export has attached [MANUAL] blocks
43
77
  - If [MANUAL] attached: flag as ORPHAN conflict (do not remove)
44
78
  - If no [MANUAL]: remove generated content cleanly
45
- - **Gap-driven rescopes** (`DELETED_EXPORT` from detect-changes §0 rule R1, verification `rescoped`) are processed here with the same removal. Step 6 also removes the provenance `entries[]` row and recomputes `stats` from the amended `brief.scope` (write.md §2/§3). The brief's `scope.amendments[]` (`action: "excluded"`) + `scope.exclude` entry must already exist — step 3 §0 HALTs otherwise, so no unscoped removal reaches here.
79
+ - **Gap-driven rescopes** (`DELETED_EXPORT` from gap-driven.md §1 rule R1, verification `rescoped`) are processed here with the same removal. §6b writes the entry's `rescope` (its `scope.amendments[]` entry, `action: "excluded"`, and its `scope.exclude` path) to the skill brief before SKILL.md, and step 5 removes the provenance `entries[]` row and recomputes `stats` from the amended `brief.scope` (write.md §2/§3). gap-driven.md §4 HALTs on a rescope that carries no `rescope`, so no unscoped removal reaches here.
46
80
 
47
81
  **Priority 2 — Process MOVED exports:**
48
82
  - Update file:line citations in generated content
83
+ - **Gap-driven:** move citations only for an export whose gap-driven.md §4 spot-check recorded `moved`. A `MOVED_EXPORT` that recorded `unknown` (the drift override among the causes), `verified` or `missing` moves none: write.md §3 leaves its line as it is.
49
84
  - Update provenance map file references
50
85
  - [MANUAL] blocks unaffected (content unchanged)
51
86
 
@@ -64,15 +99,16 @@ Apply merge in the following priority order:
64
99
  - Append new export content to appropriate section
65
100
  - Place before any [MANUAL] blocks at section boundary
66
101
  - No conflicts expected (new content, no existing [MANUAL])
102
+ - **Gap-driven cited `NEW_EXPORT` whose spot-check pinned a line** (gap-driven.md §4 recorded `verified` or `moved` for an export the provenance map does not hold): cite it as `[SRC:{source_file}:L{line}]`, where `{line}` is the citation's line for `verified` and the `new_location` line for `moved`: the line write.md §3 records in its new `source-read` entry. The spot-check found that line by the verifier's text rules, not by an ast-grep recipe, so the prefix is `SRC`, never `AST`.
67
103
 
68
104
  **Priority 6 — Process script/asset file changes (from Category D in change manifest):**
69
105
 
70
106
  Category D operates on every `file_entries[]` row regardless of `file_type`. Handle each entry by its type:
71
107
 
72
108
  - **`file_type: "script"` or `file_type: "asset"`:**
73
- - MODIFIED_FILE: queue file for re-copy from source, update `file_entries` content_hash
109
+ - MODIFIED_FILE: queue file for re-copy from `{source_root}`, update `file_entries` content_hash
74
110
  - DELETED_FILE: queue file for removal from `scripts/` or `assets/`, remove from `file_entries`
75
- - NEW_FILE: queue file for copy from source, add to `file_entries`
111
+ - NEW_FILE: queue file for copy from `{source_root}`, add to `file_entries`
76
112
  - Files in `scripts/[MANUAL]/` or `assets/[MANUAL]/` are never modified (user-authored)
77
113
  - Update Section 7b manifest table to reflect changes
78
114
  - Update `metadata.json` `scripts[]`/`assets[]` arrays and `stats.scripts_count`/`stats.assets_count`
@@ -84,7 +120,7 @@ Category D operates on every `file_entries[]` row regardless of `file_type`. Han
84
120
 
85
121
  **Priority 7 — Process new authoritative docs (from `promoted_docs_new[]` populated by §1b):**
86
122
 
87
- For each entry in the in-context `promoted_docs_new[]` list:
123
+ For each entry of `promoted_docs_new[]`, read from `{run_dir}/promoted-docs.json`:
88
124
 
89
125
  - Add a new row to `file_entries[]` in the merged provenance map with:
90
126
  - `file_name`: `"docs/authoritative/{source_path}"` (synthetic namespace — see skill-sections.md for convention)
@@ -98,20 +134,21 @@ For each entry in the in-context `promoted_docs_new[]` list:
98
134
 
99
135
  **If `promoted_docs_new[]` is empty:** skip Priority 7 silently. No report entry.
100
136
 
101
- **Priority 8 — Process STRUCTURAL_FIX entries (gap-driven, from detect-changes §0 rule R2):**
137
+ **Priority 8: Process STRUCTURAL_FIX entries (gap-driven, from gap-driven.md §1 rule R2):**
102
138
 
103
- For each `STRUCTURAL_FIX` entry forwarded by step 3 §0/1a:
139
+ For each `STRUCTURAL_FIX` entry gap-driven.md §4 forwarded:
104
140
 
105
141
  - Apply the surgical edit described in the entry's `remediation` text to the **generated output file only** (e.g., escape an unescaped `|` inside a code span, balance a fence, repair a broken intra-skill anchor in SKILL.md or a `references/*.md`).
142
+ - **A split-body consistency finding** (rule R2: the SKILL.md body and a `references/*.md` file document one export differently): edit the `references/*.md` file so it documents the export as the SKILL.md body does, whichever of the two files the gap's `Source:` names. The body is authoritative (test-skill coverage-check §1b), so never change the body to match the reference file.
106
143
  - Do **not** add, modify, or remove any provenance `entries[]` row — STRUCTURAL_FIX never touches the provenance map.
107
144
  - Preserve any [MANUAL] blocks; if the fix location overlaps a [MANUAL] block, flag as a POSITION conflict instead of editing.
108
145
  - Record in the update report: `"Structural fix: {remediation summary} at {file}:{line}"`.
109
146
 
110
147
  **If no STRUCTURAL_FIX entries:** skip Priority 8 silently.
111
148
 
112
- **Priority 8b — Process metadata-update entries (gap-driven, from detect-changes §0 rule R4):**
149
+ **Priority 8b: Process metadata-update entries (gap-driven, from gap-driven.md §1 rule R4):**
113
150
 
114
- For each `metadata update` entry forwarded by step 3 §0/1a:
151
+ For each `metadata update` entry gap-driven.md §4 forwarded:
115
152
 
116
153
  - Queue the surgical metadata patch described in the entry's `remediation` (e.g., reconcile a divergent `stats` count, add an explanatory stat) in workflow context as `metadata_patches[]` for write.md §2 to apply **before** its automatic stat recount.
117
154
  - Touch no provenance `entries[]` row and no generated markdown — this priority only stages the patch; write.md §2 applies it.
@@ -121,15 +158,13 @@ For each `metadata update` entry forwarded by step 3 §0/1a:
121
158
 
122
159
  ### 4. Check for Conflicts
123
160
 
124
- Scan all merge operations for flagged conflicts:
161
+ Scan all merge operations for flagged conflicts.
125
162
 
126
- **If ZERO conflicts:**
127
- - Report clean merge
128
- - Auto-proceed to step 05
163
+ **If ZERO conflicts:** report a clean merge.
129
164
 
130
- **If conflicts detected:**
165
+ **GATE [default: HALT]**: **if conflicts are detected, headless (`{headless_mode}` true):** conflicts require human judgment, and nothing is written yet. HALT with status `halted-for-manual-mismatch` (halt procedure: `phase: "merge:conflict-resolution"`, `reason: "{N} [MANUAL] conflict(s) need a person: {each conflict_type and section}"`). No `headless_decisions[]` entry is added.
131
166
 
132
- Present each conflict to user:
167
+ **If conflicts detected, interactive:** present each conflict to user:
133
168
 
134
169
  "**[MANUAL] Conflict Resolution Required:**
135
170
 
@@ -144,7 +179,22 @@ Present each conflict to user:
144
179
 
145
180
  Select: [K] Keep / [R] Remove / [E] Edit"
146
181
 
147
- Process each conflict with user's decision.
182
+ Process each conflict with user's decision, and record each one as it is made in the run's plan, `{run_dir}/manual-plan.json` (`{"decisions": [...]}`), one decision per [MANUAL] block by its name:
183
+
184
+ - **[K]eep:** `{"name": "<block>", "action": "keep"}`.
185
+ - **[R]emove**, and an ORPHAN the user removes: `{"name": "<block>", "action": "remove"}`.
186
+ - **[E]dit:** write the interior the user approved to `{run_dir}/manual-edit-<block>.md`, byte for byte as it goes between the block's markers, its leading and trailing newlines included, and record `{"name": "<block>", "action": "edit", "content_file": "manual-edit-<block>.md"}`. §6b writes that same file's bytes between the markers. Never type a hash: the helper below hashes the file.
187
+
188
+ **Amend the [MANUAL] inventory** (every mode, a clean merge included: then the plan holds no decision). Write `{run_dir}/manual-plan.json` (`{"decisions": []}` when there was no conflict), then, from `{project-root}`, resolve `{hashContentHelper}` ← first existing path in `{hashContentProbeOrder}` and run:
189
+
190
+ ```bash
191
+ uv run {hashContentHelper} manual-inventory-amend \
192
+ --inventory "{manual_inventory}" \
193
+ --plan "{run_dir}/manual-plan.json" \
194
+ --output "{run_dir}/manual-inventory.json"
195
+ ```
196
+
197
+ It writes the step 1 inventory without the blocks the user removed and with each edited block hashed from its approved interior. Rebind `{manual_inventory}` ← `{run_dir}/manual-inventory.json`: §6b's staged check, write.md §1, write.md §6's `fix` and write.md §7's re-check verify against it, so they check what the user approved and nothing else. On exit 1 or no JSON (a plan that names a block the inventory does not hold, or an edit with no interior), or no candidate resolves: HALT with status `blocked` (halt procedure: `phase: "merge:manual-plan"`, `path: "{run_dir}/manual-plan.json"`, its stderr as `reason`).
148
198
 
149
199
  ### 6. Compile Merge Results
150
200
 
@@ -164,41 +214,124 @@ Merge Results:
164
214
  manual_orphans_removed: [count]
165
215
  ```
166
216
 
217
+ In gap-driven mode, write what step 5's `apply` reads from merge to `{run_dir}/merge-records.json`: for each `NEW_EXPORT` or `MODIFIED_EXPORT` the provenance map does not hold and no `re-extracted` record covers (a cited export whose spot-check pinned a line, and a `Medium`, `Low` or `Info` one recorded `unknown`), the `export_type`, `params` and `return_type` its merged documentation gives, leaving out each one it does not:
218
+
219
+ ```bash
220
+ cat > "{run_dir}/merge-records.json" <<'SKF_JSON'
221
+ {"exports": [{"export_name": "<name>", "export_type": "<kind>", "params": ["<name: type>"], "return_type": "<type>"}]}
222
+ SKF_JSON
223
+ ```
224
+
167
225
  ### 6b. Write Merged Files to Disk
168
226
 
169
- Write the merged content produced by sections 3–4 directly to disk now. Later steps read from these files for validation and verification. The write must happen exactly once, here.
227
+ Write the merged content produced by sections 3–4 to disk now. Later steps read these files from disk. The write must happen exactly once, here.
170
228
 
171
- **Write SKILL.md:**
172
- - Use the `Edit` or `Write` tool to write merged SKILL.md content to `{skill_package}/SKILL.md`
173
- - Preserve UTF-8 encoding
174
- - If the source version detected during step 3 differs from the previous metadata version, create the new `{skill_package}` directory (`{skill_group}/{new_version}/`) first and write there — the previous version's directory is preserved on disk. Update `{skill_package}` in context to point at the new path.
229
+ **Renew the run lock** before anything below writes: this run may have waited at a gate past the time init.md §1b's lock goes stale. From `{project-root}`, run the acquire init.md §1b ran, with this run's own owner and the `{runLockHelper}` §1b resolved:
175
230
 
176
- **Do NOT write here:**
177
- - `metadata.json`, `provenance-map.json`, `evidence-report.md` — derived from merge + validation output, written by step 6 sections 2–4
178
- - `context-snippet.md` — regenerated from the on-disk SKILL.md + metadata.json by step 6 section 5
231
+ ```bash
232
+ uv run {runLockHelper} acquire \
233
+ --lock "{forge_data_folder}/{skill_name}/.skf-update.lock" \
234
+ --owner "{lock_owner}" \
235
+ --stale-after 60
236
+ ```
237
+
238
+ - **Exit 0 with `refreshed` true:** the lock is still this run's, now renewed; continue.
239
+ - **Exit 0 with `refreshed` false, or exit 3:** this run's lock lapsed while it waited, so another update may have changed the skill since this run read it. On exit 0 the lock was gone, or `stale_replaced` names another update's stale lock, and this acquire took it again; on exit 3 another update holds it. HALT with status `halted-for-concurrent-run` before this section writes anything: display "**This update of {skill_name} lost its run lock while it waited.** Another update of the skill may have run in the meantime, so this update wrote nothing to the skill package: run it again{on exit 3: once that update ends. {message}}." The halt procedure takes `phase: "merge:run-lock"`, `path: "{forge_data_folder}/{skill_name}/.skf-update.lock"`, `reason: "run-lock-lost: this run's lock lapsed while it waited; another update may have changed the skill since this run read it"`, or on exit 3 `reason: "another update in progress: {message}"`. The halt's release (step 3 of the halt procedure) removes a lock this acquire took.
240
+ - **Any other exit, or no JSON:** HALT with status `blocked` before this section writes anything: display "**The run lock could not be renewed:** {the message the helper printed on stderr}. This update wrote nothing to the skill package." The halt procedure takes `phase: "merge:run-lock"`, `path: "{forge_data_folder}/{skill_name}/.skf-update.lock"`, `reason: "run-lock-failed: {that message}"`.
241
+
242
+ **Choose the version this update writes** and bind `{new_version}`:
243
+
244
+ - **Gap-driven mode** (`update_mode` is `gap-driven`): a repair keeps the version it repairs — `{new_version}` is the metadata.json `version`, SKILL.md is written into the current `{skill_package}`, and the version folder below is skipped.
245
+ - **Every other mode** (normal, degraded and docs-only): `{new_version}` is `{source_version_detected}` when step 1 §6c recorded one (a higher version than the previous metadata version), otherwise the previous version with its patch number incremented, as `{skillInventoryHelper}` computes it (resolve it ← first existing path in `{skillInventoryProbeOrder}`). From `{project-root}`, run `uv run {skillInventoryHelper} version next-patch "{version}"` with the metadata.json `version` and bind `{new_version}` ← `next_patch`: `1.2.3` gives `1.2.4`, and a pre-release gives its release (`1.2.3-rc.1` gives `1.2.3`). Never increment it by hand. Both values are version folder names already: the helper drops build metadata. When no candidate resolves, or the command exits 1 (`code` `NOT_A_VERSION`: the metadata.json `version` names no version) or prints no JSON, HALT with status `halted-for-write-failure` before writing anything: "**The next version of {skill_name} could not be computed:** {the helper's `error`, or 'skf-skill-inventory.py is missing; re-install SKF'}. Nothing was written. When the metadata.json `version` names no version, set the version the skill was forged at there, then re-run." The halt procedure takes `phase: "merge:new-version-folder"`, `path: "{skill_package}/metadata.json"`, `reason: "next-version-failed: {that message}"`.
246
+
247
+ **Record what this run writes**, before its first write, so a later halt, or the next update after a crash, can undo it. From `{project-root}`, with the `{runStateHelper}` SKILL.md On Activation resolved:
179
248
 
180
- **Halt-on-tool-failure:** If any `Edit`/`Write` call errors (permission denied, disk full, path invalid, etc.), halt with status `halted-for-write-failure` and report the failure — do not proceed to step 5 validation. The skill package may be in a partial state and will need manual recovery before re-running update-skill. In `{headless_mode}`, emit the halt envelope per SKILL.md §Headless (`error: {phase: "merge:write-skill-md", path: "{skill_package}/SKILL.md", reason: "..."}`).
249
+ - **Gap-driven mode:** snapshot everything the repair may write in place:
181
250
 
182
- ### 7. Display Merge Summary
251
+ ```bash
252
+ uv run {runStateHelper} begin --run-dir "{run_dir}" --mode in-place \
253
+ --package "{skill_package}" \
254
+ --forge-version "{forge_version}" \
255
+ --brief "{forge_data_folder}/{skill_name}/skill-brief.yaml"
256
+ ```
183
257
 
184
- "**Merge Complete:**
258
+ It copies the package (each link as a link), the version's `provenance-map.json` and `evidence-report.md`, and the brief into `{run_dir}/snapshot/`. On a non-zero exit or no JSON, HALT with status `halted-for-write-failure` before writing anything (halt procedure: `phase: "merge:snapshot"`, `path: "{skill_package}"`, `reason: "snapshot-failed: {its failed[], or its message}"`).
259
+ - **Every other mode:** record the folders the next section creates:
185
260
 
186
- | Metric | Count |
187
- |--------|-------|
188
- | Exports updated | {count} |
189
- | Exports added | {count} |
190
- | Exports removed | {count} |
191
- | [MANUAL] sections preserved | {count} |
192
- | Conflicts resolved | {count} |"
261
+ ```bash
262
+ uv run {runStateHelper} begin --run-dir "{run_dir}" --mode new-version \
263
+ --created "{skill_group}/{new_version}" \
264
+ --created "{forge_data_folder}/{skill_name}/{new_version}" \
265
+ --staging "{skill_group}/{new_version}.skf-tmp" \
266
+ --skill-group "{skill_group}"
267
+ ```
193
268
 
194
- ### 8. Gate to Validation
269
+ Exit 3 (`status` `exists`) is the version-exists halt in step 1 below, with the folder its `path` names. Any other non-zero exit, or no JSON: HALT with status `halted-for-write-failure` before writing anything (halt procedure: `phase: "merge:run-state"`, `path: "{run_dir}"`, its message as `reason`).
195
270
 
196
- **Clean merge (no conflicts):** display "**Clean merge — proceeding to validation...**", then load, read the full file, and execute {nextStepFile} (auto-proceed).
271
+ **Create the version folder** (every mode but gap-driven). Each version keeps a folder of its own (`knowledge/version-paths.md`), so the previous version stays on disk unchanged and step 5 §8 can point the `active` link at the new one:
197
272
 
198
- **Conflicts were resolved (user interaction occurred):** present "**Merge complete with conflict resolution. Select:** [C] Continue to Validation" and wait for the user to confirm before loading {nextStepFile}.
273
+ 1. **Never overwrite a version.** When `begin` above exited 3, `{skill_group}/{new_version}/` or `{forge_data_folder}/{skill_name}/{new_version}/` already exists: HALT with status `halted-for-write-failure` before writing anything: "**Version {new_version} of {skill_name} already exists** at `{the folder that exists}`. Update Skill writes each version into a folder of its own, never overwrites one, and updates the version the `active` link names, which is not {new_version}. If an earlier update stopped after creating {new_version}, delete `{skill_group}/{new_version}/` and `{forge_data_folder}/{skill_name}/{new_version}/` by hand, then re-run. If you keep {new_version} on purpose, move both folders out of the way by hand before updating. Drop Skill removes a single version only when the export manifest lists it (`@Ferris DS {skill_name}`, choose {new_version}, with `--purge`); for a skill that was never exported it can only drop every version." The halt procedure takes `phase: "merge:new-version-folder"`, `path: "{the folder that exists}"`, `reason: "version {new_version} already exists; update-skill never overwrites a version"`; its rollback removes nothing, since `begin` recorded nothing. An interrupted update's folders rarely reach this halt: the next update's init.md §1b removes them when it takes over that run's stale lock.
274
+ 2. **Stage the package.** Resolve `{atomicWriteHelper}` ← first existing path in `{atomicWriteProbeOrder}` and, from `{project-root}`, run:
199
275
 
200
- **Headless (`{headless_mode}` true):**
276
+ ```bash
277
+ uv run {atomicWriteHelper} stage-dir --target "{skill_group}/{new_version}"
278
+ ```
201
279
 
202
- - Clean merge → auto-continue and append to in-context `headless_decisions[]` (surfaced via `SKF_UPDATE_RESULT_JSON` by step 7): `{gate: "merge.clean-merge-gate", default_action: "C", taken_action: "C", reason: "headless: clean merge, no conflicts to resolve"}`.
203
- - Conflicts present → halt even in headless mode (conflicts require human judgment): status `halted-for-manual-mismatch`, emitting the halt envelope per SKILL.md §Headless (`error: {phase: "merge:conflict-resolution", reason: "..."}`); no `headless_decisions[]` entry is added.
280
+ Bind `{version_staging}` ← `staging`: the empty folder `{skill_group}/{new_version}.skf-tmp` it created (it clears one an interrupted run left).
281
+ 3. **Copy the current package** `{skill_package}` to `{version_staging}/{skill_name}`, naming both without a trailing `/` — equivalent to `cp -a "{skill_package}" "{version_staging}/{skill_name}"`: SKILL.md, metadata.json, context-snippet.md, `references/`, `scripts/`, `assets/` and every other entry, each link copied as a link and never followed. The files this update does not rewrite carry over to the new version this way.
282
+ 4. **Write and verify the merged SKILL.md in the staged package**, before anything is published. Use the `Edit` or `Write` tool to write the merged SKILL.md content (UTF-8) to `{version_staging}/{skill_name}/SKILL.md`, and any `references/*.md` the merge changed into `{version_staging}/{skill_name}/references/`. Then, from `{project-root}`, check the [MANUAL] blocks against the inventory §4 amended:
204
283
 
284
+ ```bash
285
+ uv run {hashContentHelper} manual-verify "{version_staging}/{skill_name}/SKILL.md" \
286
+ --inventory "{manual_inventory}"
287
+ ```
288
+
289
+ On `ok` true, continue. On `ok` false, or a failing command: HALT with status `halted-for-manual-mismatch` before the version is published: "**[MANUAL] section integrity failure in the merged SKILL.md.** Blocks modified (interior changed): {modified}. Blocks missing (markers lost): {missing}. Nothing was published: the previous version is unchanged." The halt procedure takes `phase: "merge:verify-manual-integrity"`, `path: "{version_staging}/{skill_name}/SKILL.md"`, `reason: "[MANUAL] blocks differ from the approved inventory: modified {modified}; missing {missing}"`, and its rollback removes `{version_staging}`.
290
+ 5. **Publish it.** Run:
291
+
292
+ ```bash
293
+ uv run {atomicWriteHelper} commit-dir --target "{skill_group}/{new_version}"
294
+ ```
295
+
296
+ It renames the staged folder to `{skill_group}/{new_version}/` in one step, so no reader ever sees a half-copied version.
297
+ 6. **Create the forge folder** `{forge_data_folder}/{skill_name}/{new_version}/` and copy `provenance-map.json`, `evidence-report.md` and `extraction-rules.yaml` from `{forge_version}` into it, each when it exists: step 5 updates the provenance map and appends this update to the evidence report there, and audit-skill reads the extraction rules there. Test reports, drift reports and result files belong to the version they were made for and stay where they are.
298
+ 7. **Rebind** `{skill_package}` ← `{skill_group}/{new_version}/{skill_name}` and `{forge_version}` ← `{forge_data_folder}/{skill_name}/{new_version}`. Every later step reads and writes the new version there; `{manual_inventory}` keeps the amended path §4 bound.
299
+
300
+ If no `{atomicWriteProbeOrder}` candidate resolves, or the stage, copy, write, publish or forge-folder step fails, HALT with status `halted-for-write-failure`, naming the failed step (for a missing helper: "skf-atomic-write.py is missing; re-install SKF"). The halt procedure takes `phase: "merge:new-version-folder"`, `path: "{skill_group}/{new_version}"`, `reason: "<the failed step>: <its error>"`; its rollback removes what this section created, `{version_staging}`, `{skill_group}/{new_version}/` and `{forge_data_folder}/{skill_name}/{new_version}/`, none of which existed before `begin` recorded them. The previous version is unchanged.
301
+
302
+ **Write the merged files in place** (gap-driven mode only; every other mode wrote them in step 4 above):
303
+
304
+ 1. **The rescopes' brief amendments.** For each manifest entry with a `rescope` (rule R1), append its `scope.amendments[]` entry and add its path to `scope.exclude` in `{forge_data_folder}/{skill_name}/skill-brief.yaml`, preserving every other field; skip an amendment the brief already holds (same `action`, `category` and `path`) and a path `scope.exclude` already lists, so a re-run never adds them twice.
305
+ 2. **Stage and verify SKILL.md in the run folder.** Write the merged SKILL.md (UTF-8) to `{run_dir}/SKILL.md`, then, from `{project-root}`:
306
+
307
+ ```bash
308
+ uv run {hashContentHelper} manual-verify "{run_dir}/SKILL.md" \
309
+ --inventory "{manual_inventory}"
310
+ ```
311
+
312
+ On `ok` false, or a failing command: HALT with status `halted-for-manual-mismatch` before the package changes (halt procedure: `phase: "merge:verify-manual-integrity"`, `path: "{run_dir}/SKILL.md"`, `reason: "[MANUAL] blocks differ from the approved inventory: modified {modified}; missing {missing}"`); its rollback restores the brief step 1 amended.
313
+ 3. **Copy it over the package.** Copy `{run_dir}/SKILL.md` to `{skill_package}/SKILL.md`, and write any `references/*.md` the merge changed (merge Priority 8) into `{skill_package}/references/`.
314
+
315
+ **Do NOT write here:**
316
+ - `metadata.json`, `provenance-map.json`, `evidence-report.md`: derived from the merge output, written by step 5 sections 2–4 (the version folder above only copies the previous version's files, which step 5 then rewrites)
317
+ - `context-snippet.md`: regenerated from the on-disk SKILL.md + metadata.json by step 5 section 5
318
+
319
+ **Halt-on-tool-failure:** If any `Edit`/`Write` call or copy errors (permission denied, disk full, path invalid, etc.), HALT with status `halted-for-write-failure` and report the failure; do not proceed to step 5. The halt procedure takes `phase: "merge:write-skill-md"`, `path: "{the file that failed}"`, `reason: "<the error>"`, and its rollback puts the skill back as it was: it removes `{skill_group}/{new_version}/` and `{forge_data_folder}/{skill_name}/{new_version}/` when this run created them, and in gap-driven mode restores the package and the brief from the snapshot.
320
+
321
+ ### 7. Report Progress
322
+
323
+ Display one line from §6's counts: "**Merged:** {exports_updated} updated, {exports_added} added, {exports_removed} removed, {manual_sections_preserved} [MANUAL] sections preserved, {manual_conflicts_resolved} conflicts resolved." The report (step 6) shows the full counts.
324
+
325
+ ### 8. Route to Write
326
+
327
+ **Clean merge (no conflicts):** display "**Clean merge: proceeding to write...**", then load, read the full file, and execute {nextStepFile} (auto-proceed).
328
+
329
+ **Conflicts were resolved (user interaction occurred):** present "**Merge complete with conflict resolution. Select:** [C] Continue to Write" and wait for the user to confirm before loading {nextStepFile}.
330
+
331
+ **GATE [default: C]** (`{headless_mode}` true): a headless run reaches this gate only with a clean merge (§4 halts on a conflict before anything is written). Auto-continue and record the decision, from `{project-root}`:
332
+
333
+ ```bash
334
+ uv run {emitEnvelopeHelper} record --workflow skf-update-skill --run-dir "{run_dir}" --decision <<'SKF_JSON'
335
+ {"gate": "merge.clean-merge-gate", "default_action": "C", "taken_action": "C", "reason": "headless: clean merge, no conflicts to resolve"}
336
+ SKF_JSON
337
+ ```