bmad-module-skill-forge 2.2.0 → 4.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 (437) 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 +143 -18
  18. package/docs/verifying-a-skill.md +87 -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 +3 -3
  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 +31 -59
  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 +233 -64
  64. package/src/shared/scripts/skf-build-change-manifest.py +2753 -28
  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 +772 -0
  69. package/src/shared/scripts/skf-comention-pairs.py +1333 -123
  70. package/src/shared/scripts/skf-compare-file-hashes.py +267 -105
  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 +21 -3
  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 +197 -55
  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 +5247 -96
  86. package/src/shared/scripts/skf-extraction-inventory.py +1280 -0
  87. package/src/shared/scripts/skf-extraction-snapshot.py +664 -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 +469 -205
  92. package/src/shared/scripts/skf-github-fetch.py +365 -0
  93. package/src/shared/scripts/skf-github-probe.py +700 -0
  94. package/src/shared/scripts/skf-hash-content.py +180 -20
  95. package/src/shared/scripts/skf-language-corpora.py +1 -1
  96. package/src/shared/scripts/skf-load-provenance.py +161 -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 +143 -20
  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 +176 -28
  105. package/src/shared/scripts/skf-promote-staged.py +430 -0
  106. package/src/shared/scripts/skf-provenance-gap-dispatch.py +64 -8
  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 +155 -14
  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 +787 -121
  127. package/src/shared/scripts/skf-tessl-review.py +706 -0
  128. package/src/shared/scripts/skf-update-active-symlink.py +120 -67
  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 +23 -2
  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 +3945 -152
  138. package/src/shared/scripts/skf-write-skill-brief.py +406 -25
  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 +28 -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/health-check.md +2 -0
  168. package/src/skf-audit-skill/references/init.md +149 -210
  169. package/src/skf-audit-skill/references/re-index.md +103 -110
  170. package/src/skf-audit-skill/references/report.md +96 -33
  171. package/src/skf-audit-skill/references/semantic-diff.md +34 -25
  172. package/src/skf-audit-skill/references/severity-classify.md +79 -65
  173. package/src/skf-audit-skill/references/severity-rules.md +15 -6
  174. package/src/skf-audit-skill/references/structural-diff.md +80 -90
  175. package/src/skf-audit-skill/references/upstream-checkout.md +77 -0
  176. package/src/skf-audit-skill/scripts/render-drift-tables.py +712 -0
  177. package/src/skf-brief-skill/SKILL.md +37 -26
  178. package/src/skf-brief-skill/assets/description-voice-examples.md +1 -1
  179. package/src/skf-brief-skill/assets/scope-templates.md +18 -25
  180. package/src/skf-brief-skill/assets/skill-brief-schema.md +30 -23
  181. package/src/skf-brief-skill/customize.toml +48 -20
  182. package/src/skf-brief-skill/references/analyze-target.md +144 -127
  183. package/src/skf-brief-skill/references/confirm-brief.md +11 -9
  184. package/src/skf-brief-skill/references/draft-checkpoint.md +36 -17
  185. package/src/skf-brief-skill/references/gather-intent-ratify.md +68 -0
  186. package/src/skf-brief-skill/references/gather-intent.md +87 -182
  187. package/src/skf-brief-skill/references/headless-args.md +84 -16
  188. package/src/skf-brief-skill/references/health-check.md +1 -1
  189. package/src/skf-brief-skill/references/invocation-contract.md +18 -13
  190. package/src/skf-brief-skill/references/portfolio-similarity-check.md +1 -1
  191. package/src/skf-brief-skill/references/qmd-collection-registration.md +7 -10
  192. package/src/skf-brief-skill/references/scope-definition.md +123 -47
  193. package/src/skf-brief-skill/references/step-auto-brief.md +26 -100
  194. package/src/skf-brief-skill/references/step-auto-validate.md +20 -121
  195. package/src/skf-brief-skill/references/version-resolution.md +7 -10
  196. package/src/skf-brief-skill/references/write-brief.md +66 -57
  197. package/src/skf-campaign/SKILL.md +31 -34
  198. package/src/skf-campaign/assets/campaign-state-schema.json +25 -4
  199. package/src/skf-campaign/customize.toml +47 -16
  200. package/src/skf-campaign/references/campaign-contracts.md +39 -29
  201. package/src/skf-campaign/references/campaign-directive-spec.md +4 -2
  202. package/src/skf-campaign/references/health-check.md +7 -16
  203. package/src/skf-campaign/references/step-01-setup.md +46 -84
  204. package/src/skf-campaign/references/step-02-strategy.md +31 -30
  205. package/src/skf-campaign/references/step-03-pins.md +26 -18
  206. package/src/skf-campaign/references/step-04-provenance.md +24 -23
  207. package/src/skf-campaign/references/step-05-skill-loop.md +67 -48
  208. package/src/skf-campaign/references/step-06-batch.md +41 -34
  209. package/src/skf-campaign/references/step-07-capstone.md +40 -25
  210. package/src/skf-campaign/references/step-08-verify.md +28 -29
  211. package/src/skf-campaign/references/step-09-refine.md +29 -30
  212. package/src/skf-campaign/references/step-10-export.md +48 -36
  213. package/src/skf-campaign/references/step-11-maintenance.md +31 -34
  214. package/src/skf-campaign/references/step-resume.md +37 -68
  215. package/src/skf-campaign/scripts/campaign-deps.py +57 -18
  216. package/src/skf-campaign/scripts/campaign-parse-manifest.py +361 -54
  217. package/src/skf-campaign/scripts/campaign-provenance.py +96 -53
  218. package/src/skf-campaign/scripts/campaign-quality-gate.py +592 -0
  219. package/src/skf-campaign/scripts/campaign-render-batch.py +257 -49
  220. package/src/skf-campaign/scripts/campaign-render-kickoff.py +343 -50
  221. package/src/skf-campaign/scripts/campaign-report.py +204 -37
  222. package/src/skf-campaign/scripts/campaign-state.py +1128 -0
  223. package/src/skf-campaign/scripts/campaign-status.py +10 -74
  224. package/src/skf-campaign/scripts/campaign-validate-pins.py +30 -3
  225. package/src/skf-campaign/scripts/campaign-validate-state.py +34 -4
  226. package/src/skf-campaign/templates/campaign-brief-template.yaml +4 -5
  227. package/src/skf-campaign/templates/campaign-report-template.md +5 -1
  228. package/src/skf-campaign/templates/kickoff-template.md +0 -14
  229. package/src/skf-create-skill/SKILL.md +27 -20
  230. package/src/skf-create-skill/assets/compile-assembly-rules.md +11 -8
  231. package/src/skf-create-skill/assets/skill-sections.md +21 -11
  232. package/src/skf-create-skill/customize.toml +20 -8
  233. package/src/skf-create-skill/references/authoritative-files-protocol.md +36 -58
  234. package/src/skf-create-skill/references/batch-mode.md +81 -0
  235. package/src/skf-create-skill/references/ccc-index-check.md +27 -0
  236. package/src/skf-create-skill/references/compile.md +119 -70
  237. package/src/skf-create-skill/references/component-extraction.md +113 -91
  238. package/src/skf-create-skill/references/enrich.md +41 -23
  239. package/src/skf-create-skill/references/entry-points-by-hand.md +37 -0
  240. package/src/skf-create-skill/references/extract.md +204 -162
  241. package/src/skf-create-skill/references/extraction-patterns-by-hand.md +141 -0
  242. package/src/skf-create-skill/references/extraction-patterns-tracing.md +11 -11
  243. package/src/skf-create-skill/references/extraction-patterns.md +588 -201
  244. package/src/skf-create-skill/references/generate-artifacts.md +145 -93
  245. package/src/skf-create-skill/references/health-check.md +1 -1
  246. package/src/skf-create-skill/references/load-brief.md +53 -36
  247. package/src/skf-create-skill/references/relabel-rule.md +12 -0
  248. package/src/skf-create-skill/references/report.md +37 -57
  249. package/src/skf-create-skill/references/source-resolution-protocols.md +58 -169
  250. package/src/skf-create-skill/references/step-auto-shard.md +20 -93
  251. package/src/skf-create-skill/references/step-doc-rot.md +44 -60
  252. package/src/skf-create-skill/references/step-doc-sources.md +28 -19
  253. package/src/skf-create-skill/references/sub/ccc-discover.md +18 -7
  254. package/src/skf-create-skill/references/sub/fetch-docs.md +106 -59
  255. package/src/skf-create-skill/references/sub/fetch-temporal.md +53 -166
  256. package/src/skf-create-skill/references/tier-degradation-rules.md +18 -9
  257. package/src/skf-create-skill/references/validate.md +173 -99
  258. package/src/skf-create-skill/scripts/scan-doc-rot.py +232 -99
  259. package/src/skf-create-stack-skill/SKILL.md +29 -56
  260. package/src/skf-create-stack-skill/assets/metadata-contract.md +51 -0
  261. package/src/skf-create-stack-skill/assets/provenance-map-schema.md +15 -15
  262. package/src/skf-create-stack-skill/assets/stack-skill-template.md +23 -57
  263. package/src/skf-create-stack-skill/customize.toml +23 -12
  264. package/src/skf-create-stack-skill/references/compile-stack.md +57 -66
  265. package/src/skf-create-stack-skill/references/compose-mode-rules.md +24 -44
  266. package/src/skf-create-stack-skill/references/detect-integrations.md +92 -95
  267. package/src/skf-create-stack-skill/references/detect-manifests.md +46 -71
  268. package/src/skf-create-stack-skill/references/generate-output.md +138 -128
  269. package/src/skf-create-stack-skill/references/init.md +90 -32
  270. package/src/skf-create-stack-skill/references/integration-patterns.md +1 -17
  271. package/src/skf-create-stack-skill/references/invocation-contract.md +34 -0
  272. package/src/skf-create-stack-skill/references/manifest-patterns.md +32 -20
  273. package/src/skf-create-stack-skill/references/parallel-extract.md +112 -38
  274. package/src/skf-create-stack-skill/references/rank-and-confirm.md +57 -75
  275. package/src/skf-create-stack-skill/references/report.md +39 -33
  276. package/src/skf-create-stack-skill/references/validate.md +20 -39
  277. package/src/skf-drop-skill/SKILL.md +28 -51
  278. package/src/skf-drop-skill/customize.toml +44 -30
  279. package/src/skf-drop-skill/references/execute.md +83 -146
  280. package/src/skf-drop-skill/references/health-check.md +2 -0
  281. package/src/skf-drop-skill/references/invocation-contract.md +64 -0
  282. package/src/skf-drop-skill/references/report.md +46 -30
  283. package/src/skf-drop-skill/references/select.md +122 -124
  284. package/src/skf-drop-skill/scripts/dir-sizes.py +54 -26
  285. package/src/skf-drop-skill/scripts/drop-roster.py +322 -0
  286. package/src/skf-export-skill/SKILL.md +40 -62
  287. package/src/skf-export-skill/assets/managed-section-format.md +14 -50
  288. package/src/skf-export-skill/assets/snippet-format.md +3 -1
  289. package/src/skf-export-skill/customize.toml +42 -13
  290. package/src/skf-export-skill/references/generate-snippet.md +54 -46
  291. package/src/skf-export-skill/references/health-check.md +2 -0
  292. package/src/skf-export-skill/references/invocation-contract.md +15 -0
  293. package/src/skf-export-skill/references/load-skill.md +88 -62
  294. package/src/skf-export-skill/references/manifest-rebuild.md +9 -10
  295. package/src/skf-export-skill/references/multi-skill-mode.md +4 -4
  296. package/src/skf-export-skill/references/orphan-context-detection.md +13 -5
  297. package/src/skf-export-skill/references/orphan-row-detection.md +31 -22
  298. package/src/skf-export-skill/references/package.md +15 -73
  299. package/src/skf-export-skill/references/preflight-snippet-root-probe.md +51 -70
  300. package/src/skf-export-skill/references/result-envelope.md +31 -16
  301. package/src/skf-export-skill/references/summary.md +41 -17
  302. package/src/skf-export-skill/references/token-report.md +4 -12
  303. package/src/skf-export-skill/references/update-context.md +118 -237
  304. package/src/skf-forger/SKILL.md +61 -37
  305. package/src/skf-forger/bmad-skill-manifest.yaml +4 -1
  306. package/src/skf-forger/customize.toml +43 -0
  307. package/src/skf-forger/references/pipeline-mode.md +73 -18
  308. package/src/skf-forger/scripts/forge-status.py +299 -0
  309. package/src/skf-forger/scripts/parse-pipeline.py +322 -54
  310. package/src/skf-forger/scripts/pipeline-gate.py +428 -0
  311. package/src/skf-forger/scripts/pipeline-journal.py +1052 -0
  312. package/src/skf-quick-skill/SKILL.md +54 -53
  313. package/src/skf-quick-skill/assets/skill-template.md +4 -2
  314. package/src/skf-quick-skill/customize.toml +51 -20
  315. package/src/skf-quick-skill/references/batch-mode.md +74 -21
  316. package/src/skf-quick-skill/references/compile.md +30 -31
  317. package/src/skf-quick-skill/references/ecosystem-check.md +7 -57
  318. package/src/skf-quick-skill/references/finalize.md +69 -18
  319. package/src/skf-quick-skill/references/halt-contract.md +41 -29
  320. package/src/skf-quick-skill/references/health-check.md +5 -3
  321. package/src/skf-quick-skill/references/quick-extract.md +114 -45
  322. package/src/skf-quick-skill/references/registry-resolution.md +9 -64
  323. package/src/skf-quick-skill/references/resolve-target.md +116 -66
  324. package/src/skf-quick-skill/references/write-and-validate.md +79 -40
  325. package/src/skf-refine-architecture/SKILL.md +43 -53
  326. package/src/skf-refine-architecture/customize.toml +49 -20
  327. package/src/skf-refine-architecture/references/compile.md +97 -54
  328. package/src/skf-refine-architecture/references/exit-codes.md +30 -0
  329. package/src/skf-refine-architecture/references/finding-storage.md +21 -0
  330. package/src/skf-refine-architecture/references/gap-analysis.md +101 -38
  331. package/src/skf-refine-architecture/references/improvements.md +14 -20
  332. package/src/skf-refine-architecture/references/init.md +98 -57
  333. package/src/skf-refine-architecture/references/issue-detection.md +32 -39
  334. package/src/skf-refine-architecture/references/refinement-rules.md +37 -48
  335. package/src/skf-refine-architecture/references/report.md +65 -54
  336. package/src/skf-refine-architecture/scripts/skf-check-preservation.py +1619 -0
  337. package/src/skf-rename-skill/SKILL.md +19 -54
  338. package/src/skf-rename-skill/customize.toml +32 -26
  339. package/src/skf-rename-skill/references/execute.md +230 -184
  340. package/src/skf-rename-skill/references/exit-codes.md +7 -7
  341. package/src/skf-rename-skill/references/health-check.md +1 -7
  342. package/src/skf-rename-skill/references/invocation-contract.md +25 -0
  343. package/src/skf-rename-skill/references/report.md +63 -52
  344. package/src/skf-rename-skill/references/select.md +197 -115
  345. package/src/skf-rename-skill/scripts/skf-validate-rename-name.py +161 -21
  346. package/src/skf-setup/SKILL.md +26 -26
  347. package/src/skf-setup/customize.toml +14 -10
  348. package/src/skf-setup/references/auto-index.md +50 -63
  349. package/src/skf-setup/references/ccc-index.md +29 -90
  350. package/src/skf-setup/references/detect-and-tier.md +58 -67
  351. package/src/skf-setup/references/health-check.md +2 -0
  352. package/src/skf-setup/references/invocation-contract.md +14 -0
  353. package/src/skf-setup/references/report.md +43 -166
  354. package/src/skf-setup/references/tier-rules.md +5 -5
  355. package/src/skf-setup/references/write-config.md +34 -57
  356. package/src/skf-test-skill/SKILL.md +17 -57
  357. package/src/skf-test-skill/assets/output-section-formats.md +33 -34
  358. package/src/skf-test-skill/customize.toml +27 -13
  359. package/src/skf-test-skill/references/coherence-check.md +134 -62
  360. package/src/skf-test-skill/references/coverage-check-tiers.md +35 -0
  361. package/src/skf-test-skill/references/coverage-check.md +209 -264
  362. package/src/skf-test-skill/references/detect-mode.md +5 -5
  363. package/src/skf-test-skill/references/external-validators.md +94 -82
  364. package/src/skf-test-skill/references/health-check.md +6 -7
  365. package/src/skf-test-skill/references/init.md +164 -91
  366. package/src/skf-test-skill/references/invocation-contract.md +66 -0
  367. package/src/skf-test-skill/references/migration-section-rules.md +5 -2
  368. package/src/skf-test-skill/references/report.md +164 -142
  369. package/src/skf-test-skill/references/score.md +80 -107
  370. package/src/skf-test-skill/references/scoring-rules.md +42 -155
  371. package/src/skf-test-skill/references/source-access-protocol.md +18 -94
  372. package/src/skf-test-skill/references/step-hard-gate.md +51 -33
  373. package/src/skf-test-skill/scripts/aggregate-coherence.py +218 -30
  374. package/src/skf-test-skill/scripts/build-result-context.py +380 -0
  375. package/src/skf-test-skill/scripts/check-metadata-coherence.py +37 -4
  376. package/src/skf-test-skill/scripts/combine-external-scores.py +23 -6
  377. package/src/skf-test-skill/scripts/compute-score.py +223 -45
  378. package/src/skf-test-skill/scripts/gap-ledger.py +1666 -0
  379. package/src/skf-test-skill/scripts/hard-gate.py +203 -0
  380. package/src/skf-test-skill/scripts/load-coverage-inputs.py +1198 -0
  381. package/src/skf-test-skill/scripts/locate-export-segments.py +835 -0
  382. package/src/skf-test-skill/scripts/reconcile-coverage.py +547 -79
  383. package/src/skf-test-skill/scripts/score-signatures.py +479 -0
  384. package/src/skf-test-skill/scripts/stage-helper-payload.py +148 -0
  385. package/src/skf-test-skill/scripts/validate-inventory.py +311 -16
  386. package/src/skf-test-skill/scripts/verify-declared-numerator.py +133 -56
  387. package/src/skf-test-skill/templates/test-report-template.md +21 -15
  388. package/src/skf-update-skill/SKILL.md +38 -25
  389. package/src/skf-update-skill/customize.toml +27 -12
  390. package/src/skf-update-skill/references/detect-changes.md +253 -223
  391. package/src/skf-update-skill/references/gap-driven.md +336 -0
  392. package/src/skf-update-skill/references/health-check.md +31 -5
  393. package/src/skf-update-skill/references/init.md +254 -84
  394. package/src/skf-update-skill/references/invocation-contract.md +12 -0
  395. package/src/skf-update-skill/references/manual-section-rules.md +6 -23
  396. package/src/skf-update-skill/references/merge.md +182 -49
  397. package/src/skf-update-skill/references/re-extract.md +53 -262
  398. package/src/skf-update-skill/references/report.md +102 -35
  399. package/src/skf-update-skill/references/write.md +357 -155
  400. package/src/skf-update-skill/scripts/skf-new-file-diff.py +183 -46
  401. package/src/skf-verify-stack/SKILL.md +23 -42
  402. package/src/skf-verify-stack/assets/feasibility-report-template.md +11 -5
  403. package/src/skf-verify-stack/customize.toml +55 -22
  404. package/src/skf-verify-stack/references/coverage-patterns.md +17 -8
  405. package/src/skf-verify-stack/references/coverage.md +67 -64
  406. package/src/skf-verify-stack/references/exit-codes.md +21 -8
  407. package/src/skf-verify-stack/references/init.md +107 -62
  408. package/src/skf-verify-stack/references/integration-verification-rules.md +12 -13
  409. package/src/skf-verify-stack/references/integrations.md +106 -65
  410. package/src/skf-verify-stack/references/report.md +59 -42
  411. package/src/skf-verify-stack/references/requirements.md +32 -9
  412. package/src/skf-verify-stack/references/synthesize.md +53 -39
  413. package/src/skf-verify-stack/scripts/skf-coverage-tally.py +398 -52
  414. package/src/skf-verify-stack/scripts/skf-previous-report.py +330 -0
  415. package/src/skf-verify-stack/scripts/skf-report-delta.py +453 -49
  416. package/src/skf-verify-stack/scripts/skf-verdict-rollup.py +240 -27
  417. package/tools/cli/commands/install.js +11 -4
  418. package/tools/cli/commands/status.js +15 -3
  419. package/tools/cli/commands/update.js +11 -4
  420. package/tools/cli/lib/tool-check.js +320 -0
  421. package/tools/cli/lib/version-check.js +22 -9
  422. package/tools/cli/skf-cli.js +4 -1
  423. package/.gitattributes +0 -16
  424. package/.nvmrc +0 -1
  425. package/docs/_internal/RELEASING.md +0 -679
  426. package/release-audits/v1.0.0-launch-audit.md +0 -728
  427. package/src/skf-audit-skill/references/step-doc-drift.md +0 -177
  428. package/src/skf-brief-skill/references/headless-source-authority-detection.md +0 -26
  429. package/src/skf-campaign/manifest.yaml +0 -15
  430. package/src/skf-create-skill/assets/tessl-dismissal-rules.md +0 -106
  431. package/src/skf-create-skill/references/ecosystem-check.md +0 -74
  432. package/src/skf-drop-skill/references/headless-contract.md +0 -18
  433. package/src/skf-update-skill/references/merge-conflict-rules.md +0 -15
  434. package/src/skf-update-skill/references/remote-source-resolution.md +0 -98
  435. package/src/skf-update-skill/references/validate.md +0 -124
  436. package/tools/validate-docs-drift.js +0 -233
  437. package/tools/validate-docs-links.js +0 -665
@@ -1,28 +1,10 @@
1
1
  ---
2
2
  nextStepFile: 'token-report.md'
3
- managedSectionData: '{managedSectionFormatPath}'
4
- # Resolve `{rebuildManagedSectionsHelper}` by probing
5
- # `{rebuildManagedSectionsProbeOrder}` in order (installed SKF module path
6
- # first, src/ dev-checkout fallback); first existing path wins. §9 uses
7
- # the `replace` action for the surgical between-marker swap with
8
- # atomic temp-file + rename, marker preservation, and post-write verify.
9
- # HALT if no candidate exists — the in-prompt prose path silently regresses
10
- # the Case 4 (malformed markers) HARD HALT guarantee.
11
- rebuildManagedSectionsProbeOrder:
12
- - '{project-root}/_bmad/skf/shared/scripts/skf-rebuild-managed-sections.py'
13
- - '{project-root}/src/shared/scripts/skf-rebuild-managed-sections.py'
14
- # Resolve `{manifestOpsHelper}` similarly. §9b uses `read` / `set` for
15
- # atomic v2-schema-aware manifest mutation (handles v1→v2 migration and
16
- # `platforms`→`ides` rename internally).
17
- manifestOpsProbeOrder:
18
- - '{project-root}/_bmad/skf/shared/scripts/skf-manifest-ops.py'
19
- - '{project-root}/src/shared/scripts/skf-manifest-ops.py'
20
- # Resolve `{atomicWriteHelper}` similarly. §6 Case 1 (Create) and §6
21
- # Case 2 (Append) use it via `write` for safe artifact emission — the
22
- # in-prompt write would risk half-written files on process kill.
23
- atomicWriteProbeOrder:
24
- - '{project-root}/_bmad/skf/shared/scripts/skf-atomic-write.py'
25
- - '{project-root}/src/shared/scripts/skf-atomic-write.py'
3
+ # SKILL.md's On Activation resolved {rebuildManagedSectionsHelper}, which
4
+ # builds and writes every managed section (`assemble` builds each body,
5
+ # `check` picks the write and enforces the malformed-marker halt, `read`
6
+ # shows the old section, `insert` / `replace` write atomically and verify),
7
+ # and {manifestOpsHelper}, whose `set` records each skill in §9b.
26
8
  ---
27
9
 
28
10
  <!-- Config: communicate in {communication_language}. Render the change preview and managed section in {document_output_language}. -->
@@ -31,15 +13,15 @@ atomicWriteProbeOrder:
31
13
 
32
14
  ## STEP GOAL:
33
15
 
34
- To update the managed `<!-- SKF:BEGIN/END -->` section in the platform-appropriate context file (CLAUDE.md/AGENTS.md/.cursorrules) using the four-case logic defined by ADR-J (Create, Append, Regenerate, Malformed Markers halt), rebuilding the complete skill index from all exported skills.
16
+ To update the SKF managed section in each target context file (CLAUDE.md, AGENTS.md or .cursorrules) through `skf-rebuild-managed-sections.py`, which builds the section from every exported skill and writes it by the four cases of ADR-J (Create, Append, Regenerate, Malformed Markers halt), to record every skill of the batch in the export manifest, and then to write each skill's staged `context-snippet.md` into its package.
35
17
 
36
18
  ## Rules
37
19
 
38
- - Focus only on the managed section update in the target context file
39
- - Do not modify any content outside `<!-- SKF:BEGIN -->` and `<!-- SKF:END -->` markers
40
- - Do not write without user confirmation — this modifies shared project files
41
- - If `passive_context: false` was detected in step 1, skip this step entirely
42
- - **Multi-skill mode:** this step executes ONCE for the whole batch, not once per skill. §4b already builds the exported skill set from the manifest (plus current export targets), so a multi-skill run naturally appears as a single rebuild. The only batch adjustment is in §9b: update the manifest entry for every skill in `skill_batch` (not just one), and include all of them when computing `ides_written`. See step 1 §1c.
20
+ - The helper builds and writes the section: never type a snippet, a marker or a date into a context file, and never change the content outside the markers
21
+ - Do not write a context file without user confirmation (§8): this modifies shared project files, and a dry run writes none
22
+ - If `passive_context: false` was detected in step 1, skip to §9b: the export manifest still records the export
23
+ - **Multi-skill mode:** this step runs once for the whole batch: each body lists every skill in `skill_batch` (§4a), one gate confirms every target (§8), §9b records every skill, and §9c writes each skill's snippet. See step 1 §1c.
24
+ - Every HALT names its exit code, `halt_reason` and phase; in headless mode it first emits its envelope as `references/result-envelope.md` states
43
25
 
44
26
  ## MANDATORY SEQUENCE
45
27
 
@@ -47,194 +29,122 @@ To update the managed `<!-- SKF:BEGIN/END -->` section in the platform-appropria
47
29
 
48
30
  **If `passive_context: false` was detected in step 1:**
49
31
 
50
- "**Passive context disabled in preferences.yaml. Skipping context update.**"
32
+ "**Passive context disabled in preferences.yaml. Skipping the context files; the export manifest still records this export.**"
51
33
 
52
- Auto-proceed immediately to {nextStepFile}.
34
+ Run §9b, then auto-proceed to {nextStepFile}.
53
35
 
54
- **If `passive_context: true` (default):** Continue to step 2.
36
+ **If `passive_context: true` (default):** Continue to §2.
55
37
 
56
- ### 2. Load Managed Section Format
38
+ ### 2. Stage Folder
57
39
 
58
- Load {managedSectionData} and read the complete format template and four-case logic.
40
+ Step 3 bound `{export_stage_dir}`, the run's folder outside the project that holds each skill's snippet draft under `drafts/`. This step stages each target's new section body under its `previews/` folder, so nothing lands beside a context file before the §8 gate, and deletes the folder on every exit: the §8 dry run and cancel, the end of §9c, the orphan-row (c) Cancel and every HALT in this step.
59
41
 
60
- ### 3. Determine Target File(s)
42
+ ### 3. Determine Target Files
61
43
 
62
- Using the `target_context_files` list resolved in step 1, determine all target files. Each entry has `{context_file, skill_root}` — the context file to write and the IDE's skill directory for root path resolution.
63
-
64
- For each entry in `target_context_files`, resolve target file path: `{context_file}`
65
-
66
- **If multiple context files:** Sections 4-9a execute as a loop — one full pass per target context file. Each iteration uses the same skill index but rewrites root paths per context file's `skill_root` (section 4d) and writes to the target context file. Section 9b executes once after all iterations complete.
67
-
68
- **Processing order:** Process context files in the order listed in `target_context_files`.
44
+ Step 1 resolved `target_context_files` through `resolve-targets`: one `{context_file, skill_root, ides}` entry per file. Process the targets in that order. A context file's path is `{context_path}`, its `{context_file}` in `{project-root}`, its skill root `{target_skill_root}` is that entry's own `skill_root`, and `{target_paths}` is the `{context_path}` of every target, each quoted, space-separated, in that order.
69
45
 
70
46
  #### 3b. Detect Orphaned Platform Files (Stale Managed Sections)
71
47
 
72
- A context file becomes orphaned when its IDE is removed from `config.yaml` after a prior export. The file still contains an SKF managed section pointing to stale skill versions, but no future export will rewrite it.
73
-
74
- **Cheap pre-check (always run, ~3 file existence checks):** build `orphaned_context_files` — for each known context file in `{CLAUDE.md, .cursorrules, AGENTS.md}` that is NOT in `target_context_files`, check whether it exists on disk and contains the `<!-- SKF:BEGIN -->` marker. If yes, add `{context_file, file_path}` to `orphaned_context_files`.
75
-
76
- **If `orphaned_context_files` is non-empty:** load `references/orphan-context-detection.md` and follow its (a) clear / (b) keep / (c) rewrite gate protocol. The reference handles user prompting, headless default (keep), and downstream-state recording (`orphans_cleared`, `orphans_rewritten`, `rewrite_context_files`). When the user chooses (c), the §4–§9a loop iterates over `target_context_files + rewrite_context_files`.
77
-
78
- **If `orphaned_context_files` is empty:** proceed to §4.
79
-
80
- ### 4. Rebuild Complete Skill Index
81
-
82
- #### 4a. Read Export Manifest (v2 — version-aware)
48
+ A context file becomes orphaned when its IDE is removed from `config.yaml` after a prior export: it still holds an SKF managed section that lists stale skill versions, but no later export rewrites it.
83
49
 
84
- Read the manifest via `{manifestOpsHelper}` (resolved at §9 from `{manifestOpsProbeOrder}` — see frontmatter):
50
+ Run `check` on each file of step 1's `{other_context_files}`, the known context files no configured IDE maps to:
85
51
 
86
52
  ```bash
87
- python3 {manifestOpsHelper} {skills_output_folder} read
53
+ python3 {rebuildManagedSectionsHelper} "{context_path}" check
88
54
  ```
89
55
 
90
- The helper handles v2-schema enforcement, v1→v2 migration, and the `platforms`→`ides` rename internally. The `read` action returns a `{"status": "ok", "manifest": {...}}` envelope — parse `result["manifest"]`, **not** the top-level object (`result["exports"]` raises `KeyError`). The `manifest` value is always in canonical v2 shape regardless of on-disk state.
91
-
92
- **Schema reference:** `references/manifest-rebuild.md` documents the v2 shape, the status enum (`active`/`archived`/`deprecated`/`draft`), the v1 migration path, and the `active_version` integrity invariant. Load that file only when an inline schema reminder is needed — the helper enforces the shape so the in-prompt prose is not load-bearing.
93
-
94
- **Integrity guard:** if the helper returns an entry where `active_version` does not resolve to a key in `versions`, the manifest is inconsistent. Skip the affected skill and log: "**Manifest integrity warning:** `{skill-name}.active_version = v{active_version}` has no matching entry under `versions`. Skipping. Re-run `[EX] Export Skill` on `{skill-name}` to repair the manifest entry."
95
-
96
- **If the manifest does not exist** (first export or fresh forge): the envelope wraps an empty manifest — `result["manifest"]` is `{"schema_version": "2", "exports": {}}`, so `result["manifest"]["exports"]` is `{}`. Only the current export target will appear in the rebuilt index.
56
+ A file whose `case` is `regenerate` holds a managed section: add `{context_file, file_path}` to `orphaned_context_files`, with its `{context_path}` as `file_path`. A `malformed` one is left as it is, with the warning "`{context_file}` has malformed SKF markers, so it was left as it is: {error}". Any other case is not orphaned.
97
57
 
98
- #### 4b. Build Exported Skill Set (version-aware)
58
+ **If `orphaned_context_files` is non-empty:** load `references/orphan-context-detection.md` and follow its (a) clear / (b) keep / (c) rewrite gate protocol. It handles user prompting, the headless default (keep), and the state it records (`orphans_cleared`, `orphans_rewritten`, `rewrite_context_files`). Each file the user chose to rewrite joins the targets for §4 to §9, with `.agents/skills/` as its skill root and no IDEs, and `{target_paths}` lists it too.
99
59
 
100
- Determine the set of skills to include in the rebuilt index:
101
-
102
- 1. Start with the manifest `exports` entries that survived the §4a integrity guard — those whose `active_version` resolves to a key in `versions` (if manifest exists)
103
- 2. For each surviving skill, record its `active_version` from the manifest (v2 schema)
104
- 3. The §4a integrity guard already skipped (and warned about) any entry whose `active_version` has no matching `versions` key, so build only from those survivors — no re-check or re-warning here.
105
- 4. **Exclude deprecated skills:** If the `active_version` entry in `versions.{active_version}` has `status: "deprecated"`, skip this skill entirely — it has been dropped via drop-skill workflow and must not appear in the managed section. Log: "Skipping {skill-name} — active version v{active_version} is deprecated"
106
- 5. Add the current export target skill name (ensures it is always included even before manifest is written) — use the version from `{resolved_skill_package}/metadata.json` as its `active_version`
107
- 6. This is the **exported skill set** — each entry has a skill name and its resolved `active_version`
108
-
109
- #### 4c. Resolve and Filter Snippets (manifest-driven — replaces glob scan)
110
-
111
- Instead of globbing `{skills_output_folder}/*/context-snippet.md`, resolve snippets from the exported skill set built in 4b:
112
-
113
- **For each skill in the exported skill set:**
114
- 1. Resolve `{skill_package}` using the skill's `active_version`: `{skills_output_folder}/{skill-name}/{active_version}/{skill-name}/`
115
- 2. Read `{skill_package}/context-snippet.md`
116
- 3. **If snippet exists:** Add to skill index
117
- 4. **If snippet does not exist at the versioned path:** Check for `active` symlink at `{skills_output_folder}/{skill-name}/active/{skill-name}/context-snippet.md`.
118
- 5. **If still not found, try the flat layout:** Read `{skills_output_folder}/{skill-name}/context-snippet.md` — a skill still on the pre-versioned flat layout (see `knowledge/version-paths.md` "Migration: Flat to Versioned"). This mirrors the flat-path fallback used when resolving a skill's SKILL.md in `load-skill.md` §1, so a manifest entry (or a first-export `--all` entry) that is still flat on disk is not silently dropped from the managed section.
119
- 6. **If none of the three paths yields a snippet, skip with warning:** "Snippet missing for {skill-name} v{active_version} — skipping from managed section"
120
-
121
- **Skills NOT in the exported skill set are never scanned** — they have not been through export-skill and must not appear in the managed section (ADR-K).
122
-
123
- **If no snippets pass the filter:** Generate managed section with zero skills — header only, no skill entries.
124
-
125
- #### 4c.1 Detect Orphaned Managed-Section Rows (manifest-absent skills)
126
-
127
- A managed-section row becomes orphaned when a `[skill-name v...]` entry already exists in the prior managed section but the skill is not in the exported skill set built in 4b — typically an externally-installed skill authored in a different repo and dropped into `{skills_output_folder}` without going through export-skill. Strict ADR-K would silently drop such rows, but the user's managed section is load-bearing — silent removal is a regression.
128
-
129
- **Cheap pre-check (always run before §5 assembly).** Scan **every** target context file (not just the first), deduplicate by `(skill_name, version)`, and present one consolidated gate. Asymmetric orphans — a row present in `.cursorrules` but absent from `CLAUDE.md`, or vice versa — must be detected; otherwise the §4 rebuild loop silently overwrites the orphan-bearing file's content (ADR-J violation: silent loss of user content).
130
-
131
- The parse / dedup-by-`(skill_name, version)` / set-diff-against-the-exported-set is deterministic marker surgery with one correct answer per input — a mis-parsed row silently drops an installed skill from the rebuilt managed section (the ADR-J/K regression this gate guards against). Delegate it to `{rebuildManagedSectionsHelper}` (resolve from `{rebuildManagedSectionsProbeOrder}` in frontmatter — first existing path wins; if no candidate exists, the same HALT as §9 applies: exit code 4, `halt_reason: "context-rebuild-failed"`). Do not re-derive the rows in-prompt.
60
+ **If `orphaned_context_files` is empty:** proceed to §4.
132
61
 
133
- 1. Run the detector once across **every** target context file — pass each `target_context_files[].context_file` as a positional argument, and the comma-joined list of skill **names** from the exported skill set built in §4b (version is not needed for the orphan test) as `--exported-skills`:
62
+ ### 4. Build the Managed Section
134
63
 
135
- ```bash
136
- python3 {rebuildManagedSectionsHelper} orphan-detect {context-file-1} {context-file-2} … --exported-skills {name1,name2,…}
137
- ```
64
+ #### 4a. The Skills It Lists
138
65
 
139
- 2. Set `orphan_managed_rows = result["orphan_managed_rows"]`. The helper reads each context file that exists and has a `<!-- SKF:BEGIN -->` marker, parses its `[skill-name v...]` rows, drops those whose `skill_name` is in the exported set, and deduplicates the survivors by `(skill_name, version)` — first-seen `snippet_text` wins (divergent snippets across files for the same `(skill, version)` are a user-content asymmetry, but `(b) Preserve verbatim` writes one canonical row to every target file, so first-seen is deterministic), and each file the row appears in is appended to a sorted `source_files`. The returned shape is:
66
+ `assemble` lists each skill of the export manifest whose active version is not deprecated and, through `--include`, every skill in `skill_batch` at the version in its `{resolved_skill_package}/metadata.json`, so a first export, a batch member the manifest does not list yet, and a skill the step 1 manifest-lag guard resolved to a newer version all appear at the version this export publishes. Bind `{batch_includes}` to the comma-joined `{skill-name}@{version}` of every skill in `skill_batch`. `--snippet-dir` hands it the drafts step 3 staged, so a batch skill's row is its new snippet.
140
67
 
141
- ```json
142
- {"status": "ok", "orphan_managed_rows": [{"skill_name": "…", "version": "…", "snippet_text": "…", "source_files": ["…"]}]}
143
- ```
68
+ #### 4b. Assemble One Body per Target
144
69
 
145
- Each entry's `snippet_text` is the byte-exact prior snippet (re-emitted unchanged if (b) is chosen — the only surviving copy of an orphan's snippet is this known-exact string, never model-reconstructed); `source_files` carries provenance for the gate display and the audit `deviations[]` entry. A missing file, a file with no marker, or a section with no skill rows contributes nothing — the helper already handles those, so the list is empty in those cases.
70
+ For each target, run:
146
71
 
147
- **If `orphan_managed_rows` is non-empty:** load `references/orphan-row-detection.md` and follow its (a) Drop / (b) Preserve verbatim / (c) Cancel gate protocol. The reference handles user prompting (with per-orphan `source_files` provenance), headless default (Preserve verbatim), `deviations[]` recording (including `source_files` per orphan for audit), and §6 result-contract integration.
72
+ ```bash
73
+ python3 {rebuildManagedSectionsHelper} assemble "{context_path}" \
74
+ --skills-folder "{skills_output_folder}" --skill-root "{target_skill_root}" \
75
+ --include {batch_includes} --snippet-dir "{export_stage_dir}/drafts" \
76
+ --orphan-sources {target_paths} --orphans {orphan_mode} \
77
+ --out "{export_stage_dir}/previews/{context_file}.skf-content" \
78
+ [--skill-root-override "{snippet_skill_root_override}"]
79
+ ```
148
80
 
149
- **If `orphan_managed_rows` is empty:** proceed to §4d.
81
+ Add `--skill-root-override` only when `{snippet_skill_root_override}` is set (by `config.yaml`, or for this run by step 1's snippet-root option (d)). `{orphan_mode}` is `keep` unless §4c.1 drops the orphan rows. The helper writes the body to the `--out` file, with no marker and no trailing newline, and prints its result as JSON. From each target's result bind `{content_file}` ← `content_file`, `{n_single}` ← `n_single` and `{n_stack}` ← `n_stack`. A non-zero exit writes nothing: HALT (exit code 4, `halt_reason: "context-rebuild-failed"`, phase `update-context §4b`) and report `{context_file}: {error}` (for example a context file that is not UTF-8 text: the error says how to fix it).
150
82
 
151
- #### 4d. Rewrite Root Paths for Target Context File
83
+ When the first result's `malformed_context_files` is not empty, run the §5 `check` on those files now and take its `malformed` HALT, before §4c.1 asks anything: a target whose `<!-- SKF:BEGIN` marker no `<!-- SKF:END -->` closes is never written.
152
84
 
153
- The context-snippet.md files on disk contain root paths for the IDE they were originally exported to. When assembling the managed section for the current target context file, rewrite root paths if they differ from the target's `skill_root`.
85
+ #### 4c. Report What Was Left Out
154
86
 
155
- **Generic root path rewrite algorithm** (no hardcoded prefix list):
87
+ Every call reads the same manifest and snippets, so report these once, from the first result:
156
88
 
157
- For each snippet being included in the managed section:
89
+ - each `skipped_integrity[]` entry: "**Manifest integrity warning:** `{skill_name}`: {reason}. Skipping. Re-run `[EX] Export Skill` on `{skill_name}` to repair the manifest entry."
90
+ - each `skipped_deprecated[]` entry: "Skipping {skill_name}: active version v{version} is deprecated"
91
+ - each `skipped_missing_snippet[]` entry: "Snippet missing for {skill_name} v{version}: skipping from managed section"
92
+ - each `skipped_malformed_snippet[]` entry: "Snippet of {skill_name} v{version} skipped: {reason}"
93
+ - each `warnings[]` line as it is
158
94
 
159
- 1. Read the `root:` value from the snippet's first line — it has the form `root: {prefix}{skill-name}/`
160
- 2. Extract the current prefix by stripping the trailing `{skill-name}/` from the root value
161
- 3. **Resolve the effective target prefix:** If `snippet_skill_root_override` is set in config.yaml, use the override value as the effective target prefix for this rebuild — by the override contract every skill in the repo lives under that single shared on-disk directory, so the managed section must reference the override for *every* snippet (not just the ones that already match it). Otherwise, use the current target's `skill_root` as the effective target prefix.
162
- 4. Compare the extracted prefix against the effective target prefix
163
- 5. If they differ, replace the prefix with the effective target prefix, preserving the skill name. When the override is set, this rewrites stale per-IDE prefixes carried by sibling snippets that were exported before the override was adopted, so the rebuilt managed section uniformly references the real on-disk location instead of mixing override and per-IDE paths.
164
- 6. Example: if snippet has `root: .claude/skills/my-lib/` but target skill_root is `.windsurf/skills/`, rewrite to `root: .windsurf/skills/my-lib/`
165
- 7. Example: if `snippet_skill_root_override: skills/` is set, the effective target prefix is `skills/` regardless of the IDE mapping. A snippet with `root: skills/my-lib/` passes through unchanged; a sibling snippet with `root: .claude/skills/my-other/` (carried over from a pre-override export) is rewritten to `root: skills/my-other/`.
95
+ With no skill to list, each body holds the header alone (`0 skills|0 stack`).
166
96
 
167
- This algorithm handles any IDE's skill root path — including future IDEs — without enumerating known prefixes. The legacy `skills/` prefix (no leading dot) may appear in draft snippets generated by create-skill/quick-skill before export.
97
+ #### 4c.1 Orphaned Managed-Section Rows
168
98
 
169
- **Sort skills alphabetically by name.**
99
+ A managed-section row is orphaned when the export manifest has no entry for its skill and this run does not export it: typically a skill installed from another repo into `{skills_output_folder}` without going through export-skill. Strict ADR-K would drop such a row, but the row is often the only copy of that skill's snippet, so the helper keeps it verbatim unless told to drop it, and lists it in `orphan_rows` (each with `skill_name`, `version`, `snippet_text` and `source_files`). Every call scans the same files in the same order, so bind `orphan_rows` from the first result.
170
100
 
171
- Count totals:
172
- - Total skills (single type)
173
- - Total stack skills
101
+ **If `orphan_rows` is non-empty:** load `references/orphan-row-detection.md` and follow its (a) Drop / (b) Preserve verbatim / (c) Cancel gate protocol. It handles user prompting, the headless default (Preserve verbatim), the `deviations[]` record and the result-contract integration. On (a), run §4b again for every target with `--orphans drop`.
174
102
 
175
- ### 5. Generate Managed Section
103
+ **If `orphan_rows` is empty:** proceed to §5.
176
104
 
177
- Assemble the managed section in **two shapes** — the §9 write paths consume different forms, and conflating them double-wraps the markers.
105
+ ### 5. Check Each Target File
178
106
 
179
- **`{managed_section_inner}`** — the between-marker body only, **no** `<!-- SKF:BEGIN/END -->` markers. The `insert` and `replace` helper actions supply the markers (and the `updated:` timestamp) themselves, so they take this inner form:
107
+ Run `check` on each target:
180
108
 
181
- ```markdown
182
- [SKF Skills]|{n} skills|{m} stack
183
- |IMPORTANT: Prefer documented APIs over training data.
184
- |When using a listed library, read its SKILL.md before writing code.
185
- |
186
- |{skill-snippet-1}
187
- |
188
- |{skill-snippet-2}
189
- |
190
- |{skill-snippet-N}
109
+ ```bash
110
+ python3 {rebuildManagedSectionsHelper} "{context_path}" check
191
111
  ```
192
112
 
193
- **`{managed_section_full}`** — `{managed_section_inner}` wrapped in markers. Used for the new-file create path (atomic write, which writes the text verbatim) and the §7 preview:
194
-
195
- ```markdown
196
- <!-- SKF:BEGIN updated:{current-date} -->
197
- {managed_section_inner}
198
- <!-- SKF:END -->
199
- ```
113
+ Bind `{case}` ← `case` for that target. The case picks the §9 write:
200
114
 
201
- ### 6. Detect Case and Prepare Changes
115
+ | `case` | The target file | §9 write |
116
+ |---|---|---|
117
+ | `create` | does not exist | `insert`, which creates it with the section |
118
+ | `append` | has no managed section | `insert`, which adds the section at its end |
119
+ | `regenerate` | has a managed section | `replace`, which swaps that section and keeps everything outside the markers |
120
+ | `malformed` | has a `<!-- SKF:BEGIN` marker that no `<!-- SKF:END -->` closes | none: HALT |
202
121
 
203
- **Check target file at `{target-file}`:**
122
+ - **`malformed`:** HALT (exit code 5, `halt_reason: "malformed-markers"`, phase `update-context §5`) with the helper's `error`, which names the line of the marker and the fix (restore the `<!-- SKF:END -->` line, or remove the stray `<!-- SKF:BEGIN`, then re-run). Write nothing to any target: the helper refuses such a file, because a write there would take the user's lines below the marker for part of the section.
204
123
 
205
- **Case 1: Create (file does not exist)**
206
- - Action: Create new file with managed section only
207
- - Diff: Show entire managed section as new content
124
+ ### 6. Read the Current Sections
208
125
 
209
- **Case 2: Append (file exists, no `<!-- SKF:BEGIN` marker found)**
210
- - Action: Read existing content, append managed section at end
211
- - Diff: Show managed section being appended after existing content
212
- - Preserved: ALL existing content untouched
126
+ For each `regenerate` target, read the section §9 replaces:
213
127
 
214
- **Case 3: Regenerate (file contains `<!-- SKF:BEGIN` and `<!-- SKF:END -->`)**
215
- - Action: Replace everything between markers (inclusive) with new managed section
216
- - Diff: Show old managed section vs new managed section
217
- - Preserved: ALL content before `<!-- SKF:BEGIN` and after `<!-- SKF:END -->`
128
+ ```bash
129
+ python3 {rebuildManagedSectionsHelper} "{context_path}" read
130
+ ```
218
131
 
219
- **Case 4: Malformed markers (file contains `<!-- SKF:BEGIN` but no `<!-- SKF:END -->`)**
220
- - Action: HALT (exit code 5, `halt_reason: "malformed-markers"`) with warning: "Malformed SKF markers detected in `{target-file}` — `<!-- SKF:BEGIN` found but `<!-- SKF:END -->` is missing. Please restore the end marker manually before running export."
221
- - Do NOT attempt to write or append — the file is in an inconsistent state.
222
- - In headless mode, emit the error envelope per `references/result-envelope.md` with `manifest_path: null`, `context_files_updated: []`.
132
+ Bind `{old_section}` ← `content` for that target; §7 shows it beside the new body.
223
133
 
224
134
  ### 7. Present Change Preview
225
135
 
226
136
  "**Context update prepared.{if multi-platform: ' (platform {i}/{total}: {platform})'}**
227
137
 
228
- **Target:** `{target-file}`
229
- **Case:** {1: Create / 2: Append / 3: Regenerate}
230
- **Skills in index:** {n} skills, {m} stack
138
+ **Target:** `{context_file}`
139
+ **Case:** {Create / Append / Regenerate}
140
+ **Skills in index:** {n_single} skills, {n_stack} stack
231
141
 
232
142
  **Changes:**
233
143
 
234
- {Show diff preview:}
235
- - For Case 1: Show full file content to be created
236
- - For Case 2: Show `...existing content preserved...\n\n{managed section}`
237
- - For Case 3: Show old section vs new section with surrounding context preserved
144
+ {Show the diff preview from the new body in `{content_file}`:}
145
+ - For Create: the new file, which holds only the section
146
+ - For Append: `...existing content preserved...` followed by the section
147
+ - For Regenerate: `{old_section}` beside the new body, with the content outside the markers preserved
238
148
 
239
149
  **Content outside markers:** {preserved / n/a (new file)}
240
150
 
@@ -246,118 +156,89 @@ Assemble the managed section in **two shapes** — the §9 write paths consume d
246
156
 
247
157
  "**[DRY RUN] No files will be written. Preview above shows what would change.**
248
158
 
159
+ **[DRY RUN] Export manifest would be updated for {skill-name-list}: ides: {ides_written}.**
160
+
249
161
  **Proceeding to token report...**"
250
162
 
251
- Auto-proceed to {nextStepFile}.
163
+ List every skill in `skill_batch`, and give `{ides_written}` as §9b defines it, over the targets above, or `none` when it is empty. §9 to §9c do not run: delete the `{export_stage_dir}` folder, then auto-proceed to {nextStepFile}.
252
164
 
253
165
  **If NOT dry-run:**
254
166
 
255
- Display: "**Select:** [C] Continue — write changes to {target-file} | [X] Cancel and exit (or type `cancel` / `exit` / `:q`)"
167
+ Display: "**Select:** [C] Continue: write changes to {context_file} | [X] Cancel and exit (or type `cancel` / `exit` / `:q`)"
256
168
 
257
169
  **Multi-target behavior:** When processing multiple context files, present all previews together before asking for a single confirmation. After confirmation, write all target files sequentially, verifying each one.
258
170
 
259
- "**Targets:** {list all context-file → target-file pairs}
171
+ "**Targets:** {list each context_file with its case}
260
172
  **Ready to write changes to all targets?**"
261
173
 
262
174
  Display: "**Select:** [C] Continue — write changes to all targets | [X] Cancel and exit"
263
175
 
264
176
  #### Gate handling
265
177
 
266
- - **[C]** — write the changes to all target files (or the single target), verify each write succeeded, then load, read entirely, and execute `{nextStepFile}`.
267
- - **[X]** / `cancel` / `exit` / `:q` — Display "Cancelled — no context files were written." and HALT (exit code 6, `halt_reason: "user-cancelled"`). In headless, emit the error envelope per `references/result-envelope.md` with the resolved `skills`, `context_files_updated: []`, and `manifest_path: null`.
178
+ - **[C]**: write the targets (§9), record the export (§9b) and write the snippets (§9c), then load, read entirely, and execute `{nextStepFile}`.
179
+ - **[X]** / `cancel` / `exit` / `:q`: delete the `{export_stage_dir}` folder, display "Cancelled: no context files were written." and HALT (exit code 6, `halt_reason: "user-cancelled"`, phase `update-context §8`).
268
180
  - **Any other input** — help the user respond, then redisplay this gate.
269
- - **Headless** [default C]: auto-approve with [C], log "headless: auto-approve context file update".
270
181
  - **Dry-run**: auto-proceed without writing.
182
+ - **GATE [default: C]**: headless, record the decision in the run sink with the command below, log "headless: auto-approve context file update", then auto-approve with [C]. If `record` exits non-zero, display its error line and go on: a failed `record` never stops the run.
271
183
 
272
- ### 9. Write and Verify (Non-Dry-Run Only)
273
-
274
- After user confirms with 'C', resolve the helpers in parallel — these are independent file-existence checks that batch into one tool-call message:
275
-
276
- - `{rebuildManagedSectionsHelper}` ← first existing path in `{rebuildManagedSectionsProbeOrder}` (used for Cases 2 and 3)
277
- - `{atomicWriteHelper}` ← first existing path in `{atomicWriteProbeOrder}` (used for Case 1)
278
- - `{manifestOpsHelper}` ← first existing path in `{manifestOpsProbeOrder}` (used in §9b)
279
-
280
- If any helper has no existing candidate, HALT (exit code 4, `halt_reason: "context-rebuild-failed"`) and emit the error envelope per `references/result-envelope.md` — the rewrite's safety guarantees depend on these helpers and a fall-through to LLM-driven writes would silently regress atomicity, marker preservation, and the Case 4 malformed-marker HARD HALT contract.
281
-
282
- **Stage content via a shell-safe channel (all cases).** Managed-section snippets routinely contain backticks and `$` — API names like `` `Room::connect(...)` ``, tokens like `$threshold` and `${…}`. Inlining them as a double-quoted shell argument (`--content "…"`) or via `echo "…"` lets bash run command substitution and variable expansion, silently corrupting the written bytes — and because the helper's byte-identity verify runs against the already-corrupted string, it would still report success. No quoting style is safe (content can also contain single quotes, e.g. `'eager' | 'on-demand'`), so **never** inline the section into the command. Instead write the assembled section to a staging file with your file-write tool (which performs no shell interpretation), then feed it to the helper via stdin redirection — the helper reads stdin whenever `--content` is absent:
184
+ ```bash
185
+ uv run {emitEnvelopeHelper} record --workflow skf-export-skill --run-dir "{run_dir}" --decision <<'SKF_JSON'
186
+ {"gate":"update-context.write-confirmation","default_action":"C","taken_action":"C","reason":"headless: auto-approve context file update"}
187
+ SKF_JSON
188
+ ```
283
189
 
284
- - For **Cases 2 and 3**, write `{managed_section_inner}` to `{target-file}.skf-content` with **no trailing newline** (the helper appends `\n<!-- SKF:END -->` itself; a trailing newline would insert a blank line before the end marker).
285
- - For **Case 1**, write `{managed_section_full}` to `{target-file}.skf-content` followed by a single trailing newline (matches the verbatim file-end newline convention).
286
- - After the helper reports success, delete `{target-file}.skf-content`.
190
+ ### 9. Write and Verify (Non-Dry-Run Only)
287
191
 
288
- For each target context file, dispatch by case:
192
+ For each target, in order, feed the body §4b staged at `{content_file}` to the write its §5 case picked, by stdin redirection. Never pass a body inline as `--content "…"` or through `echo`: snippets carry backticks, `$` and quotes, which the shell expands, and the helper checks the text it received, so it would report success on corrupted bytes.
289
193
 
290
- **Case 1 (Create — file does not exist):**
194
+ **Create and Append:**
291
195
 
292
196
  ```bash
293
- python3 {atomicWriteHelper} write --target "{target-file}" < "{target-file}.skf-content"
197
+ python3 {rebuildManagedSectionsHelper} "{context_path}" insert < "{content_file}"
294
198
  ```
295
199
 
296
- The helper stages the content into `<target>.skf-tmp`, fsyncs, and atomically renames into place. This path writes verbatim, so the staging file holds the **marker-bearing** `{managed_section_full}`.
297
-
298
- **Case 2 (Append — file exists, no `<!-- SKF:BEGIN` marker):**
200
+ **Regenerate:**
299
201
 
300
202
  ```bash
301
- python3 {rebuildManagedSectionsHelper} {target-file} insert < "{target-file}.skf-content"
203
+ python3 {rebuildManagedSectionsHelper} "{context_path}" replace < "{content_file}"
302
204
  ```
303
205
 
304
- The helper appends the managed section to the end of the file via the same atomic temp-file + rename pattern. The staging file holds the **inner-only** `{managed_section_inner}` — the helper adds the markers and `updated:` timestamp itself; marker-bearing text double-wraps them.
206
+ Both write the `<!-- SKF:BEGIN updated:{date} -->` and `<!-- SKF:END -->` markers around the body themselves (the date from the clock), write the file atomically (temp file + rename) and read it back to check the markers and the bytes outside them. They refuse (exit 1) a body that holds a marker of its own, and a file whose markers became malformed after §5, and leave that file unchanged. They print their result as JSON on stdout and exit 0 only when `status` is `"ok"`.
305
207
 
306
- **Case 3 (Regenerate — file contains `<!-- SKF:BEGIN` and `<!-- SKF:END -->`):**
208
+ On a non-zero exit, bind `{context_error}` ← `error` (the helper's stderr when stdout holds no JSON, such as a Python traceback), HALT (exit code 4, `halt_reason: "context-rebuild-failed"`, phase `update-context §9`) and report `{context_file}: {context_error}`. The targets already written stay written.
307
209
 
308
- ```bash
309
- python3 {rebuildManagedSectionsHelper} {target-file} replace < "{target-file}.skf-content"
310
- ```
210
+ On success per file, report "**{context_file} updated successfully.** Verified by `{rebuildManagedSectionsHelper}`." and add it to `context_files_updated`.
311
211
 
312
- The helper performs the surgical between-marker swap with post-write verification (markers present, content outside markers byte-identical). The staging file holds the **inner-only** `{managed_section_inner}` — as with `insert`, the helper supplies the markers; marker-bearing text double-wraps them.
212
+ ### 9b. Update Export Manifest
313
213
 
314
- **Case 4 (malformed markers — already HALTed in §6):** never reaches here.
214
+ **This section runs once, after every target is written** (§1 sends a run with passive context off straight here; a dry run runs no `set`, as the dry-run paragraph below says). It records each skill in `skill_batch` at the version in its `{resolved_skill_package}/metadata.json`.
315
215
 
316
- **Verification (deferred to helpers):** the `replace`/`insert`/`write` actions above each perform their own verification. Treat any non-zero exit as a write failure:
216
+ **`ides_written`** is the list of IDE identifiers from `config.yaml` `ides` (e.g. `claude-code`, `cursor`, `github-copilot`) whose context file §9 wrote: the `ides` of each `target_context_files` entry §9 wrote, joined, deduplicated and sorted. It is never a context file name (`CLAUDE.md`) or a skill root (`.claude/skills/`). A file §3b rewrote adds no IDE, and with passive context off `ides_written` is empty.
317
217
 
318
- - HALT (exit code 4, `halt_reason: "context-rebuild-failed"`) and report `{target-file}: {captured stderr}`.
319
- - In headless mode, emit the error envelope per `references/result-envelope.md`.
320
- - Continue to the next target file only on success — partial-batch writes are acceptable in single-skill mode but the overall envelope reports per-target outcomes.
218
+ For each skill, run `set`, with `--ides` only when `ides_written` is not empty:
321
219
 
322
- On success per file, report: "**{target-file} updated successfully.** Verified by `{rebuildManagedSectionsHelper}` (or `{atomicWriteHelper}` for Case 1)."
220
+ ```bash
221
+ python3 {manifestOpsHelper} {skills_output_folder} set {skill-name} {version} [--ides {ides_written}]
222
+ ```
223
+
224
+ `{ides_written}` is comma-joined. `set` does the whole update, migrating a v1 manifest first, and writes the manifest atomically (the v2 shape is in `references/manifest-rebuild.md`). It exits 0 with `status: "ok"` only once the manifest is written, so that result confirms the write. Once every `set` has exited 0, bind `{manifest_path}` ← `{skills_output_folder}/.export-manifest.json`, which step 6 reports; it stays null on a dry run and after a failed write.
323
225
 
324
- ### 9b. Update Export Manifest (Non-Dry-Run Only)
226
+ **Dry-run mode:** Do NOT update the manifest. Display: "**[DRY RUN] Export manifest would be updated for {skill-name-list}: ides: {ides_written}.**" (list every skill in `skill_batch`; `ides_written` is empty with passive context off, so show `none`). A dry run with passive context on displayed this line at §8 and never reaches this section. Then auto-proceed to {nextStepFile}.
325
227
 
326
- **This section executes ONCE after all context-file iterations complete** (outside the per-context-file loop defined in section 3). Only IDEs whose target context files were successfully written and verified in section 9 are recorded.
228
+ **Error handling:** If `set` exits non-zero, HALT (exit code 4, `halt_reason: "manifest-write-failed"`, phase `update-context §9b`) with the helper's `error` (its stderr when stdout holds no JSON). The context files §9 wrote stay written, and no snippet is written: re-run `[EX] Export Skill` on the batch, which writes the same sections again, records the manifest and writes the snippets.
327
229
 
328
- **`ides` field definition:** `ides` is the list of IDE identifiers from `config.yaml.ides` (e.g. `claude-code`, `cursor`, `github-copilot`) whose context files were successfully written and verified in section 9. It is NOT the context file name (`CLAUDE.md`) and NOT the skill root path (`.claude/skills/`). Each IDE → context file → skill root mapping is defined in `{managedSectionData}`.
230
+ ### 9c. Write the Snippets
329
231
 
330
- 1. Read `{skills_output_folder}/.export-manifest.json` (or start with `{"schema_version": "2", "exports": {}}` if it does not exist)
331
- 2. Ensure `schema_version` is `"2"` (if v1 was migrated in section 4a, the migrated structure is already in context). If any version entry still has a legacy `platforms` key, rename it to `ides` in place (see §4a).
332
- 3. Compute `ides_written` — the set of IDE identifiers from `config.yaml.ides` whose mapped context file was successfully written in section 9 (deduplicated, sorted). When `--context-file` was passed explicitly, `ides_written` contains only the IDEs that map to that single context file.
333
- 4. For each skill in `skill_batch` (multi-skill mode) — or the single current skill (single-skill mode) — add or update its entry in v2 format:
334
- ```json
335
- "{skill-name}": {
336
- "active_version": "{version}",
337
- "versions": {
338
- "{version}": {
339
- "ides": ["{ides_written}"],
340
- "last_exported": "{current-date}",
341
- "status": "active"
342
- }
343
- }
344
- }
345
- ```
346
- - `{version}` is the version from each skill's `{resolved_skill_package}/metadata.json`
347
- - If the skill already has a manifest entry:
348
- - Set `active_version` to the current version
349
- - If the version already exists in `versions`, union its existing `ides` with `ides_written` (deduplicate, keep sorted), refresh `last_exported`, and set `status: "active"`
350
- - If this is a new version, add it to `versions` with `status: "active"` and set any previously-active version's status to `"archived"`
351
- - Preserve all other version entries in `versions` (do not delete archived versions)
352
- 5. Write the updated manifest atomically via `{manifestOpsHelper}` after all skills in the batch have been applied. For each skill / version pair, invoke:
232
+ **This section runs last, after §9b, and only when step 3 staged the snippets**: a run with passive context off has none, and a dry run never reaches it.
353
233
 
354
- ```bash
355
- python3 {manifestOpsHelper} {skills_output_folder} set {skill-name} {version} --ides {ides_written}
356
- ```
234
+ For each skill in `skill_batch`, copy its measured draft into its package, byte for byte, so the count step 3 measured is the count of the written file:
357
235
 
358
- `{ides_written}` is the comma-joined sorted IDE set computed in step 3. The helper handles v2-schema validation, v1→v2 migration, and `platforms`→`ides` rename internally — no in-prompt JSON manipulation needed. Each `set` invocation unions the supplied `--ides` into the version entry's existing `ides` (deduplicated, sorted) server-side and refreshes `last_exported`. After all skills have been set, re-read the manifest via `{manifestOpsHelper} {skills_output_folder} read` (the v2 manifest is under the `manifest` key of the returned envelope — see §4a) to confirm the final state matches expectations.
236
+ ```bash
237
+ cp "{export_stage_dir}/drafts/{skill-name}/context-snippet.md" "{resolved_skill_package}/context-snippet.md"
238
+ ```
359
239
 
360
- **Dry-run mode:** Do NOT update the manifest. Display: "**[DRY RUN] Export manifest would be updated for {skill-name-list} — ides: {ides_written}.**" (list every skill in `skill_batch`)
240
+ Report "**{skill-name}: context-snippet.md written** to `{resolved_skill_package}/context-snippet.md`." and add the file to `snippets_written`, which step 6 lists in the result contract.
361
241
 
362
- **Error handling:** If `{manifestOpsHelper}` exits non-zero, HALT (exit code 4, `halt_reason: "manifest-write-failed"`) with the captured `stderr`. The managed section was already written successfully; the operator's recovery path is to manually reconcile the on-disk managed section with the manifest, then re-run `[EX] Export Skill --all` to refresh the manifest. In headless mode, emit the error envelope per `references/result-envelope.md` with `manifest_path: null` and the partial `context_files_updated` list.
242
+ On a failed copy, HALT (exit code 4, `halt_reason: "write-failed"`, phase `update-context §9c`) and report `{skill-name}: context-snippet.md was not written: {error}`. The context files, the export manifest and the snippets copied before it stay written: re-run `[EX] Export Skill` on the skills whose snippet was not written (this one and the ones after it).
363
243
 
244
+ Once every snippet is written, delete the `{export_stage_dir}` folder.