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
@@ -10,8 +10,8 @@
10
10
 
11
11
  ### Structural Findings
12
12
 
13
- | # | Type | Detail | Line |
14
- |---|------|--------|------|
13
+ | # | Type | Severity | Detail | Line |
14
+ |---|------|----------|--------|------|
15
15
  | {per-issue rows} |
16
16
 
17
17
  **Structural Issues:** {count}
@@ -44,8 +44,8 @@ Only rendered when `references/` directory exists alongside SKILL.md.
44
44
 
45
45
  ### Reference Validation
46
46
 
47
- | Reference | Type | Line | Target Exists | Accurate | Issues |
48
- |-----------|------|------|--------------|----------|--------|
47
+ | Reference | Type | Line | Target Exists | Accurate | Severity | Issues |
48
+ |-----------|------|------|--------------|----------|----------|--------|
49
49
  | {per-reference rows} |
50
50
 
51
51
  ### Integration Pattern Completeness
@@ -61,39 +61,45 @@ Only rendered when `references/` directory exists alongside SKILL.md.
61
61
  - **Combined Coherence:** {percentage}%
62
62
  ```
63
63
 
64
- ## Gap Report Section
64
+ ## Ledger Record Format
65
65
 
66
- ```markdown
67
- ## Gap Report
66
+ Every gap a stage finds is one JSON record in the run's gap ledger, `{forge_version}/test-findings-{run_id}.json`, appended through `scripts/gap-ledger.py append`; no stage writes gap entries into the report by hand:
68
67
 
69
- **Total Gaps:** {N}
70
- **Blocking (Critical + High):** {N}
71
- **Non-blocking (Medium + Low + Info):** {N}
68
+ ```json
69
+ {
70
+ "severity": "Critical | High | Medium | Low | Info",
71
+ "category": "the category of its Gap Severity table row, such as missing-export",
72
+ "title": "one line",
73
+ "source": "file:line, or a section reference when no line applies",
74
+ "remediation": "the exact action that fixes the gap",
75
+ "issue": "what is wrong (optional)",
76
+ "export": "the export the gap is about (optional; set it whenever the gap is about one export)"
77
+ }
78
+ ```
72
79
 
73
- ### Remediation Summary
80
+ - `severity` and `category` come from one row of the Gap Severity table in `references/scoring-rules.md`. The script refuses a category outside its vocabulary, which `uv run scripts/gap-ledger.py categories` lists.
81
+ - `source` is a `file:line` pair whenever a line applies, with nothing after it: update-skill reads the pair as the gap's citation. A gap inside the skill package cites `SKILL.md:{line}` or `references/{file}.md:{line}`.
82
+ - `remediation` follows the Remediation Quality Rules below and names each file it touches.
83
+ - Leave out `id`, `group` and `stage`: the script assigns them (`GAP-{NNN}` in the order the gaps were recorded, the group from the category, the stage from `--stage`).
74
84
 
75
- | Severity | Count | Estimated Effort |
76
- |----------|-------|-----------------|
77
- | Critical | {N} | {description} |
78
- | High | {N} | {description} |
79
- | Medium | {N} | {description} |
80
- | Low | {N} | {description} |
81
- | Info | {N} | {description} |
82
- | **Total** | **{N}** | |
83
- ```
85
+ ## Gap Report
84
86
 
85
- ## Gap Entry Format
87
+ `uv run scripts/gap-ledger.py render --ledger <ledger> --heading` prints the Gap Report, its effort column included, and report.md §4c writes it unchanged: it is never written by hand.
88
+
89
+ ## Discovery Quality Subsection
90
+
91
+ Written under the Gap Report by report.md §4c:
86
92
 
87
93
  ```markdown
88
- ### GAP-{NNN}: {Brief title}
94
+ ### Discovery Quality
89
95
 
90
- **Severity:** {Critical|High|Medium|Low|Info}
91
- **Category:** {Coverage|Coherence|Structural}
92
- **Source:** {file:line or section reference}
96
+ **Discovery Test:** {PASS (3/3) | WARN (2/3) | FAIL ({N}/3 misrouted) | skipped: {reason} | not run: the hard gate blocked the run}
93
97
 
94
- **Issue:** {Precise description of what is wrong or missing}
98
+ | # | Prompt | Selected Skill | Result |
99
+ |---|--------|----------------|--------|
100
+ | {per-prompt rows, when the test ran} |
95
101
 
96
- **Remediation:** {Exact action to fix this gap}
102
+ {description optimization hints from report.md §4b.4, when any}
97
103
  ```
98
104
 
99
105
  ## Remediation Quality Rules
@@ -102,10 +108,3 @@ Only rendered when `references/` directory exists alongside SKILL.md.
102
108
  - **Bad:** "Document the missing function."
103
109
  - **Good:** "Update signature in SKILL.md line 78 from `(date: Date) => string` to `(date: Date, format?: string) => string` to match source at `src/utils.ts:42`."
104
110
  - **Bad:** "Fix the signature mismatch."
105
-
106
- ## Effort Estimation Guidelines
107
-
108
- - Critical/High gaps: typically require reading source code and writing documentation
109
- - Medium gaps: typically require adding type definitions or interface docs
110
- - Low gaps: typically require adding examples or metadata
111
- - Info: optional improvements, no action required
@@ -1,8 +1,8 @@
1
1
  # DO NOT EDIT -- overwritten on every update.
2
2
  #
3
3
  # Workflow customization surface for skf-test-skill.
4
- # Team overrides: _bmad/custom/skf-test-skill.toml (under {project-root})
5
- # Personal overrides: _bmad/custom/skf-test-skill.user.toml (under {project-root})
4
+ # Team overrides: {project-root}/_bmad/custom/skf-test-skill.toml
5
+ # Personal overrides: {project-root}/_bmad/custom/skf-test-skill.user.toml
6
6
 
7
7
  [workflow]
8
8
 
@@ -10,9 +10,10 @@
10
10
  # scalars: override wins • arrays (persistent_facts, activation_steps_*): append
11
11
  # arrays-of-tables with `code`/`id`: replace matching items, append new ones.
12
12
 
13
- # Steps to run before the standard activation (uv probe, config load).
14
- # Overrides append. Use for org-wide pre-flight checks (auth, network,
15
- # compliance) that must precede any quality-test work.
13
+ # Steps SKILL.md On Activation step 3 runs right after the customization
14
+ # resolve: config.yaml is loaded and headless mode resolved by then, and no
15
+ # stage has run. Overrides append. Use for org-wide pre-flight checks (auth,
16
+ # network, compliance) that must precede any quality-test work.
16
17
 
17
18
  activation_steps_prepend = []
18
19
 
@@ -26,11 +27,18 @@ activation_steps_append = []
26
27
  # (house style, severity policies, grading guardrails).
27
28
  # Overrides append.
28
29
  #
29
- # Each entry is either:
30
+ # Each entry is one of:
30
31
  # - a literal sentence, e.g. "Test failures of CRITICAL severity block release."
31
32
  # - a file reference prefixed with `file:`, e.g.
32
33
  # "file:{project-root}/docs/test-policy.md" (globs supported; file
33
34
  # contents are loaded and treated as facts).
35
+ # - an entry prefixed with `!`, which loads nothing and drops each earlier
36
+ # entry it names.
37
+ #
38
+ # The default below loads every project-context.md under {project-root}.
39
+ # Overrides append, so they cannot delete it; to stop loading those files,
40
+ # set in {project-root}/_bmad/custom/skf-test-skill.toml:
41
+ # persistent_facts = ["!file:{project-root}/**/project-context.md"]
34
42
 
35
43
  persistent_facts = [
36
44
  "file:{project-root}/**/project-context.md",
@@ -42,16 +50,22 @@ persistent_facts = [
42
50
  # without forking the skill. Empty string = use the bundled default.
43
51
 
44
52
  test_report_template_path = ""
45
- output_formats_path = ""
46
- scoring_rules_path = ""
53
+
54
+ # The scoring rules and the output formats are not overridable: scripts own
55
+ # the weights and the verdict rules, and the hard gate reads the Gap Severity
56
+ # table, so a house-style copy could change what blocks export.
47
57
 
48
58
  # Pass threshold (percent). Precedence: CLI `--threshold=<N>` > per-pipeline
49
- # defaults (from init.md §1b lookup table) > this scalar > bundled fallback 80.
50
- # Override here to change the org-wide default without forking the skill.
59
+ # defaults (the init.md §1b lookup table, which outranks this scalar in
60
+ # forge-auto, forge, forge-quick and campaign runs) > this scalar > bundled
61
+ # fallback 80. Override here to change the org-wide default without forking
62
+ # the skill. A value above 80 is a target: a run scoring 80 or more still
63
+ # passes through the threshold fallback (with an evidence report), while a
64
+ # run a cap forced to FAIL stays FAIL at any threshold.
51
65
  default_threshold = 80
52
66
 
53
67
  # Optional post-finalization hook. When non-empty, the workflow invokes:
54
- # <on_complete> --result-path=<path-to-skf-test-skill-result-{run_id}.json>
55
- # after the result JSON is finalized. Failures are recorded to
56
- # workflow_warnings[] but never fail the workflow. Empty = no-op.
68
+ # <on_complete> --result-path=<the per-run skf-test-skill-result-<YYYYMMDD-HHmmss>.json>
69
+ # after the result JSON is finalized. A failure is shown to the user but
70
+ # never fails the workflow. Empty = no-op.
57
71
  on_complete = ""
@@ -1,10 +1,18 @@
1
1
  ---
2
2
  nextStepFile: 'external-validators.md'
3
- outputFile: '{forge_version}/test-report-{skill_name}-{run_id}.md'
4
- outputFormatsFile: '{outputFormatsPath}'
5
- scoringRulesFile: '{scoringRulesPath}'
3
+ outputFile: '{report_file}'
4
+ outputFormatsFile: 'assets/output-section-formats.md'
5
+ scoringRulesFile: 'references/scoring-rules.md'
6
6
  coherenceAggregationScript: 'scripts/aggregate-coherence.py'
7
+ locateExportSegmentsScript: 'scripts/locate-export-segments.py'
7
8
  migrationSectionRules: 'references/migration-section-rules.md'
9
+ # §6 records every gap this step finds in the run's gap ledger, which the
10
+ # hard gate (step 4c) reads and the Gap Report is rendered from.
11
+ ledgerFile: '{forge_version}/test-findings-{run_id}.json'
12
+ gapLedgerScript: 'scripts/gap-ledger.py'
13
+ # Resolve `{scanSkillMdStructureHelper}` to the first existing path (§1): both
14
+ # modes take their structural facts, export usage counts and reference
15
+ # checks from it, so no step greps SKILL.md by hand.
8
16
  scanSkillMdStructureProbeOrder:
9
17
  - '{project-root}/_bmad/skf/shared/scripts/skf-scan-skill-md-structure.py'
10
18
  - '{project-root}/src/shared/scripts/skf-scan-skill-md-structure.py'
@@ -18,10 +26,20 @@ scanSkillMdStructureProbeOrder:
18
26
 
19
27
  Validate internal consistency of the skill documentation. In contextual mode (stack skills): verify that all cross-references in SKILL.md point to real files, types match their declarations, and integration patterns are complete. In naive mode (individual skills): perform basic structural validation only.
20
28
 
29
+ **Halt envelope.** Every HALT in this step names its `halt_reason` and phase and carries exit code 1. It releases the run lock first, whatever the release prints: from `{project-root}`, run `uv run {runLockHelper} release --lock "{forge_version}/.test-skill.lock" --owner "{run_owner}"` (SKILL.md Workflow Rules). In headless mode it then writes `{"phase": "<phase>", "reason": "<the halt message>", "halt_reason": "<halt_reason>", "skill_name": "{skill_name}", "report_path": "{report_file}"}`, adding `"path"` when the halt names one, to `{run_dir}/halt.json` and runs:
30
+
31
+ ```bash
32
+ uv run {emitEnvelopeHelper} emit-halt --workflow skf-test-skill --run-dir "{run_dir}" --target stderr < "{run_dir}/halt.json"
33
+ ```
34
+
35
+ Display the line it prints, as the run's last line, then stop. If the emitter exits non-zero or prints no line, display the halt message alone. An interactive HALT displays its message and emits nothing.
36
+
21
37
  ### 1. Check Test Mode
22
38
 
23
39
  Read `testMode` from `{outputFile}` frontmatter.
24
40
 
41
+ **Resolve `{scanSkillMdStructureHelper}`** from `{scanSkillMdStructureProbeOrder}`; first existing path wins. Both modes run it. If no candidate exists, HALT (`halt_reason: "helper-missing"`, phase `coherence-check:scan`). Any command of it below that exits non-zero: HALT with its stderr (`halt_reason: "helper-failed"`, phase `coherence-check:scan`).
42
+
25
43
  **IF naive mode → Execute Naive Coherence (Section 2)**
26
44
  **IF contextual mode → Execute Contextual Coherence (Sections 3-5)**
27
45
 
@@ -29,46 +47,60 @@ Read `testMode` from `{outputFile}` frontmatter.
29
47
 
30
48
  Perform the following explicit checks (no hand-waving — most use a single deterministic script; severity assignments are binding; do not relax them).
31
49
 
32
- **Resolve `{scanSkillMdStructureHelper}`** from `{scanSkillMdStructureProbeOrder}`; first existing path wins. HALT if no candidate exists.
33
-
34
- **2.0 Run the structural scan.** Invoke `{scanSkillMdStructureHelper}` twice and parse the JSON outputs. These results back §§2.1, 2.2, 2.3, and 2.6 — do not re-implement those checks with grep/sed/awk loops.
50
+ **2.0 Run the structural scan.** Invoke `{scanSkillMdStructureHelper}` (§1) twice, saving each output to the run folder. These results back §§2.1, 2.2, 2.3, 2.6 and 2.7: do not re-implement those checks with grep/sed/awk loops.
35
51
 
36
52
  ```bash
37
- uv run {scanSkillMdStructureHelper} scan {skill-md} --required-sections
38
- uv run {scanSkillMdStructureHelper} scan {skill-md}
53
+ uv run {scanSkillMdStructureHelper} scan "{resolved_skill_package}/SKILL.md" --required-sections > "{run_dir}/required-sections.json"
54
+ uv run {scanSkillMdStructureHelper} scan "{resolved_skill_package}/SKILL.md" > "{run_dir}/structure.json"
39
55
  ```
40
56
 
41
- The first call returns `{ description: {satisfied, matched_synonym, tried[]}, usage: {...}, api_surface: {...} }`. The second returns `{ unbalanced_fences, fence_count, bare_opening_fences[{line,text}], table_drift[{line,section,expected_cols,actual_cols,row}] }`. Hold both JSON blobs for the checks below.
57
+ The first call returns `{ description: {satisfied, matched_synonym, tried[]}, usage: {...}, api_surface: {...}, frontmatter_description, outline[{line,level,text}] }`. The second returns `{ unbalanced_fences, fence_count, bare_opening_fences[{line,text}], table_drift[{line,section,expected_cols,actual_cols,row}], scripts_assets{folders[],section,missing} }`. Hold both JSON blobs, which the files keep, for the checks below.
42
58
 
43
59
  **2.1 Required sections present.** Read the first JSON blob from §2.0. For each of the three families (`description`, `usage`, `api_surface`):
44
60
 
45
61
  - `satisfied: true` → no finding.
46
- - `satisfied: false` AND family is `description` AND the SKILL.md frontmatter has a non-empty `description` field → no finding (the frontmatter alternative satisfies the family per the original rule).
47
- - Otherwise → **High severity** finding: `naive-coherence — missing required section: {family}` (the `tried[]` list from the JSON identifies which synonyms were checked: `Description`/`Overview`/`Purpose`/`Summary` for description; `Usage`/`Usage Patterns`/`Examples`/`How to use`/`Quickstart`/`Quick Start`/`Getting Started`/`Common Workflows`/`Adoption Steps` for usage; `API`/`API Surface`/`Exports`/`Key Exports`/`Public API`/`Interface`/`Reference`/`Key API Summary`/`Pattern Surface` for api_surface).
62
+ - `satisfied: false`, family `description` and `frontmatter_description: true` (a non-empty frontmatter `description` satisfies the family) → no finding.
63
+ - `satisfied: false` otherwise: read `outline`, each heading of the body with its line. When one heading's section serves the family (it shows how to call the library, for `usage`; it lists the library's exports, for `api_surface`; it says what the library is for, for `description`), there is no finding: name that heading and its line in the Coherence Analysis, and pass the family to §6 as `--served`. Otherwise → **High severity** finding: `naive-coherence: missing required section: {family}`.
48
64
 
49
- The script matches case-insensitively and tolerates `##`/`###` heading levels. SKF-template skills' headings are first-class synonyms baked into the script — the Deep/create-skill `## Quick Start`, `## Common Workflows`, and `## Key API Summary`, the quick-skill `## Usage Patterns` and `## Key Exports`, and the reference-app overrides `## Adoption Steps` (usage) and `## Pattern Surface` (api_surface) — so they all surface with `satisfied: true` and the corresponding `matched_synonym` field.
65
+ The script matches the full heading text, case-insensitively, at any heading level, outside the frontmatter and fenced code. Its synonyms, `tried[]`, include every SKF template and override heading, so a skill built from a template reports `satisfied: true` and the `matched_synonym`.
50
66
 
51
- **2.2 Code fence balance.** Read `unbalanced_fences` from the second JSON blob. **`true` → High severity** finding: `naive-coherence — unbalanced code fence (unclosed block)` (the JSON's `fence_count` may be cited in the detail).
67
+ **2.2 Code fence balance.** Read `unbalanced_fences` from the second JSON blob. **`true` → High severity** finding: `naive-coherence: unbalanced code fence (unclosed block)` (the JSON's `fence_count` may be cited in the detail).
52
68
 
53
- **2.3 Language tags on opening fences.** Read `bare_opening_fences[]` from the second JSON blob. The script already runs the stateful open/close scan — closing fences are never reported. For each entry, emit a **Medium severity** finding: `naive-coherence — opening code fence at line {entry.line} missing language tag`.
69
+ **2.3 Language tags on opening fences.** Read `bare_opening_fences[]` from the second JSON blob. The script already runs the stateful open/close scan, so closing fences are never reported. For each entry, emit a **Medium severity** finding: `naive-coherence: opening code fence at line {entry.line} missing language tag`.
54
70
 
55
- **2.4 Exports cross-used in a usage-family section.** For each function name reported in the step 3 subagent inventory (`exports[].name` where `kind == "function"` or `kind == "method"`):
56
- - Determine the usage-family search scope:
57
- - **Single-body skill** (no `references/` directory, or `## Full*` sections carry real content): the span from §2.1's `matched_synonym` anchor to the next `^## ` anchor.
58
- - **Split-body skill** (a `references/` directory exists alongside SKILL.md AND the SKILL.md `## Full*` sections are stubs/pointers): the union of EVERY usage-family heading present in SKILL.md (`Usage`/`Usage Patterns`/`Examples`/`How to use`/`Quickstart`/`Quick Start`/`Getting Started`/`Common Workflows`/`Adoption Steps`/`Key API Summary`/`Pattern Surface`/`Key Exports`), each from its anchor to the next `^## ` anchor, PLUS the full text of every file under `references/`.
59
- - `grep -c "{export.name}"` across that scope and sum the counts.
60
- - **Zero occurrences across the entire scope → High severity** finding: `naive-coherence — exported {kind} \`{name}\` is not referenced in any usage-family section or reference file`. This catches the "documented but unused" failure mode that trivially fails discovery testing. A method referenced in any usage-family section OR any `references/` file satisfies the check.
71
+ **2.4 Exports cross-used in a usage-family section.** The scanner counts how often each function and method export of the validated inventory (the file step 3 wrote) is used in the usage-family scope, so no name is grepped by hand:
61
72
 
62
- **2.5 Async/sync consistency.** For every export with `async` in its description prose (grep for `\basync\b` in the description segment), check the corresponding code example segment for `await` / `async` keywords:
63
- - Description says async + example shows no `await` → **High severity** finding: `naive-coherence — \`{name}\` described as async but example lacks \`await\``
64
- - Description says sync + example uses `await {name}` → **High severity** finding: `naive-coherence — \`{name}\` described as sync but example awaits it`
73
+ ```bash
74
+ uv run {scanSkillMdStructureHelper} usage-scope "{resolved_skill_package}/SKILL.md" --exports "{run_dir}/inventory.json" --kinds function,method [--body single] > "{run_dir}/usage-scope.json"
75
+ ```
65
76
 
66
- **2.6 Table syntax.** Read `table_drift[]` from the second JSON blob (§2.0). The script normalizes escaped pipes (`\|`, used inside TypeScript union types such as `string \| undefined`) before splitting and compares each row against its header's column count, so a plain `split on |` false-positive cannot occur here. For each entry, emit a **Medium severity** finding: `naive-coherence — table row at line {entry.line} has {entry.actual_cols} columns; header has {entry.expected_cols}` (the `entry.section` and `entry.row` fields populate the detail when present).
77
+ The script decides split-body from the `references/` folder alone; whether the `## Full*` sections are stubs is your judgment, so pass `--body single` when a `references/` directory exists but those sections carry real content. Read `zero_usage[]` from the output:
78
+ - **Zero occurrences across the entire scope → Medium severity** finding, one per `zero_usage[]` entry: `naive-coherence: exported {kind} \`{name}\` is not referenced in any usage-family section or reference file`. This catches the "documented but unused" failure mode that trivially fails discovery testing. Like a missing export, it is a completeness gap, so it does not block the hard gate.
67
79
 
68
- **2.7 Scripts & Assets section.** If `{skillDir}/scripts/` or `{skillDir}/assets/` exists, `grep -n '^## Scripts' SKILL.md`:
69
- - Directory exists AND no `## Scripts` section → **Medium severity** finding: `naive-coherence — scripts/assets directory exists but Scripts & Assets section missing` (per `{scoringRulesFile}`)
80
+ **2.5 Async/sync consistency.** `{locateExportSegmentsScript}` reports the facts: for each export the step 3 inventory lists with `kind` `function` or `method`, where the skill describes it (`descriptions[]`: the heading sections, table rows, list items and paragraphs that name it in code, and the signature lines that declare it) and each call to it in fenced code, with whether the call awaits it. It reads the names from the validated inventory file itself, keeping the `function` and `method` entries, so no name is copied by hand. Skip this check when the inventory has no such export; otherwise run the script (it resolves relative to the skill root):
70
81
 
71
- **Hard rule:** 0 findings across §§2.1–2.7 = naive coherence PASS. ≥1 finding = rerank per the severity rubric above; the count and severity list are appended to the Coherence Analysis output in §6.
82
+ ```bash
83
+ uv run {locateExportSegmentsScript} --inventory "{run_dir}/inventory.json" --skill-dir "{resolved_skill_package}"
84
+ ```
85
+
86
+ The script judges no meaning. For each `exports[]` entry, read its `descriptions[]` and decide what they assert about **this** export. The word `async` in a description decides nothing:
87
+
88
+ - **async**: the caller must await what it returns (a promise, a coroutine or a future), as its signature or its description says. A Kotlin `suspend` function needs no `await`, so it makes no async claim here.
89
+ - **sync**: it returns its result directly, for example as the blocking counterpart of an async export.
90
+ - **no claim**: nothing says how it returns. A description that names a paired sync or async variant (`readFileSync` as "the sync counterpart of the async `readFile`"), or says async about another API, asserts nothing about this export.
91
+
92
+ Then, for each export:
93
+
94
+ - **async**, no call is awaited (`awaitedCount` is 0) and no unawaited call hands its result on → **High severity** finding: `naive-coherence: \`{name}\` described as async but example lacks \`await\`` (cite the first call's `file` and `line`). A call hands its result on when its `chainedMember` waits for it (`then`, `catch`, `join`, `get`), the example returns it (`return fetchData(x)` in an async function) or stores it and awaits it later: read the call lines before raising the finding.
95
+ - **sync** and `awaitedCount` is above 0 → **High severity** finding: `naive-coherence: \`{name}\` described as sync but example awaits it` (cite the first awaited call).
96
+ - Otherwise no finding. The names in `notCalled[]` appear in no example, so they raise none.
97
+
98
+ **2.6 Table syntax.** Read `table_drift[]` from the second JSON blob (§2.0). The script normalizes escaped pipes (`\|`, used inside TypeScript union types such as `string \| undefined`) before splitting and compares each row against its header's column count, so a plain `split on |` false-positive cannot occur here. For each entry, emit a **Medium severity** finding: `naive-coherence: table row at line {entry.line} has {entry.actual_cols} columns; header has {entry.expected_cols}` (the `entry.section` and `entry.row` fields populate the detail when present).
99
+
100
+ **2.7 Scripts & Assets section.** Read `scripts_assets` from the second JSON blob (§2.0): `folders` names the `scripts/` and `assets/` folders beside SKILL.md, and `section` the first heading that starts with `Scripts` (null when there is none).
101
+ - `missing` is true (a folder exists AND no Scripts heading) → **Medium severity** finding: `naive-coherence: scripts/assets directory exists but Scripts & Assets section missing` (per `{scoringRulesFile}`)
102
+
103
+ **Hard rule:** 0 findings across §§2.1–2.7 = naive coherence PASS. ≥1 finding = rerank per the severity rubric above; the count and severity list go into the Coherence Analysis section §6 writes.
72
104
 
73
105
  Build the findings list:
74
106
 
@@ -77,14 +109,14 @@ Build the findings list:
77
109
  "structural_issues": [
78
110
  {"type": "missing_section", "severity": "High", "detail": "No 'Usage' section found", "line": null},
79
111
  {"type": "unbalanced_fence", "severity": "High", "detail": "3 opening fences, 2 closing", "line": null},
80
- {"type": "export_not_in_usage", "severity": "High", "detail": "exported function `formatDate` never referenced in Usage section", "line": 42},
112
+ {"type": "export_not_in_usage", "severity": "Medium", "detail": "exported function `formatDate` never referenced in Usage section", "line": 42},
81
113
  {"type": "async_mismatch", "severity": "High", "detail": "`fetchData` described async but example lacks await", "line": 67}
82
114
  ],
83
115
  "issues_found": 4
84
116
  }
85
117
  ```
86
118
 
87
- **After naive coherence → Execute Section 2b if gate conditions met, then skip to Section 6 (Append Results)**
119
+ **After naive coherence → Execute Section 2b if gate conditions met, then skip to Section 6 (Write Results)**
88
120
 
89
121
  ### 2b. Migration/Deprecation Verification (Mode-Independent)
90
122
 
@@ -92,50 +124,57 @@ Apply rules from `{migrationSectionRules}`. That file is the single source of
92
124
  truth for the gate, scope, and case rules; §5b below applies the same rules on
93
125
  the contextual path.
94
126
 
95
- **After Section 2b (naive path) → Skip to Section 6 (Append Results)**
127
+ **After Section 2b (naive path) → Skip to Section 6 (Write Results)**
96
128
 
97
129
  ### 3. Contextual Mode: Extract References
98
130
 
99
- Scan SKILL.md for all cross-references:
131
+ SKILL.md's cross-references come in two kinds, and each has one owner:
132
+
133
+ - **File-path and script/asset references**: every markdown link to a file (`[types](src/types.ts)`, `[guide](references/guide.md)`) and every `references/`, `scripts/` or `assets/` path mentioned in prose or inline code (`references/{file}.md`, `scripts/{file}`, `assets/{file}`), by the scanner's Reference extraction rules. Whether the target exists, and where it really lives, has one right answer, so the scanner extracts them and checks them. Any other path written outside a link (`../shared/types.ts` in inline code, an import specifier) is not checked: it usually names a file in the reader's project or a module, not one the skill ships:
100
134
 
101
- **Reference types to extract:**
102
- - File path references (`./path/to/file.ts`, `../shared/types.ts`)
103
- - Skill references (`See SKILL.md for {other-skill}`, `Integrates with {package}`)
104
- - Type imports (`import { Type } from './module'`)
105
- - Integration pattern references (middleware chains, plugin hooks, shared state)
106
- - Script/asset references (`scripts/{file}`, `assets/{file}`) in SKILL.md body
135
+ ```bash
136
+ uv run {scanSkillMdStructureHelper} reference-check "{resolved_skill_package}/SKILL.md" [--source-root "{source_path}"] [--skills-root "{skills_output_folder}"] > "{run_dir}/references.json"
137
+ ```
107
138
 
108
- Delegate to a subagent that grep/regexes SKILL.md for reference patterns and returns only this JSON shape — no prose, no commentary, no markdown fences: `{"references_found": [{"line": N, "type": "file-path|skill|type-import|integration-pattern|script-asset", "target": "..."}]}`. Parent strips wrapping markdown fences (if present) before parsing. If subagent unavailable, scan in main thread.
139
+ Pass `--source-root` when metadata.json records the extraction tree (`{source_path}`), and `--skills-root` for a stack skill: a stack's constituent cross-references legitimately resolve to `skills/{name}/active` under `{skills_output_folder}`, which lies outside `{skillDir}`, and a stack's metadata.json records no single `source_path` to anchor them. The scanner resolves each target against the SKILL.md folder through every symlink (`os.path.realpath`) before the root check, so a symlink that points outside every root is still caught, and gives it a `status`: `ok` (inside a root, present), `missing` (inside a root, nothing there) or `escapes` (outside every root: `../../../etc/passwd`, an absolute path to an unrelated folder, a symlink redirection outside the skill, its source or a stack's skills tree). Do not check these targets again by hand or through subagents, and do not validate an escaping target's contents: the escape itself is the finding.
140
+ - **Skill references, type imports and integration-pattern references** (`See SKILL.md for {other-skill}`, `Integrates with {package}`, `import { Type } from './module'`, middleware chains, plugin hooks, shared state): whether one is accurate takes judgment. Delegate to a subagent that reads SKILL.md and returns only this JSON shape (no prose, no commentary, no markdown fences): `{"references_found": [{"line": N, "type": "skill|type-import|integration-pattern", "target": "..."}]}`. Parent strips wrapping markdown fences (if present) before parsing. If subagent unavailable, scan in main thread.
109
141
 
110
142
  ### 4. Contextual Mode: Validate Each Reference
111
143
 
112
- For EACH reference found, delegate to a subagent that:
144
+ The scanned references need no further check: `{run_dir}/references.json` holds their statuses.
113
145
 
114
- 1. Checks if the target exists (file exists, skill exists, type is declared)
115
- 2. If target exists, validates the reference is accurate:
116
- - File path references: file exists at specified path
146
+ Delegate the references §3's subagent found, in one batch, to a subagent that, for each one:
147
+
148
+ 1. Checks if the target exists (the skill exists in the skills output folder, the type is declared, the integration point is in the code)
149
+ 2. If the target exists, validates the reference is accurate:
117
150
  - Type imports: type is actually exported from the referenced module
118
151
  - Skill references: referenced skill exists in skills output folder
119
152
  - Integration patterns: documented pattern matches actual implementation
120
- - Script/asset references: verify the referenced file exists in the skill's `scripts/` or `assets/` directory
121
- 3. Returns only this JSON shape per reference — no prose, no commentary, no markdown fences: `{"reference": "...", "line": N, "target_exists": <bool>, "type_match": <bool>, "signature_match": <bool>, "issues": ["..."]}`
122
-
123
- Parent strips wrapping markdown fences (if present) before parsing. If subagent unavailable, validate each reference in main thread.
153
+ 3. Returns only a JSON array, one object per reference, with no prose, no commentary and no markdown fences: `{"reference": "...", "line": N, "target_exists": <bool>, "type_match": <bool>, "signature_match": <bool>, "issues": ["..."]}`
124
154
 
125
- 4. **Scripts/assets directory check:** If a `scripts/` or `assets/` directory exists alongside SKILL.md, verify that a "Scripts & Assets" section (Section 7b) is present in SKILL.md. This directory-level check applies in both modes (naive mode performs it in Section 2; contextual mode performs it here alongside per-reference validation). Flag absence as Medium severity gap per `{scoringRulesFile}`.
155
+ Save its response, as it came back, to `{run_dir}/judged-references.json` with the Write tool (no file when §3 found no such reference). If subagent unavailable, validate each reference in main thread and save the same array. §5c counts the valid references from both files, and classifies the invalid ones.
126
156
 
127
- 5. **Path containment:** for every resolved reference target, compute its canonical path (`os.path.realpath`) and require that it lives inside `{skillDir}`, inside `{source_path}` (the extraction tree recorded in metadata.json), OR — for stack skills — inside `{skills_output_folder}`. The third root applies only here in contextual mode: a stack's constituent cross-references legitimately resolve to `skills/{name}/active` under `{skills_output_folder}`, which lies outside `{skillDir}`, and a stack's metadata.json records no single `source_path` to anchor them. References whose canonical path escapes all applicable roots (e.g. `../../../etc/passwd`, absolute paths to unrelated dirs, symlink redirections outside the skill, its source, or — for a stack — the skills output tree) are **High severity** findings: `coherence — reference escapes skill/source sandbox: {raw_ref} → {canonical_path}`. Canonicalization happens before the root check, so a symlink that points outside every applicable root is still caught. Do not validate the target's contents for escaping references — the escape itself is the finding.
157
+ When `scripts_assets.missing` in `{run_dir}/references.json` is true (a `scripts/` or `assets/` folder beside SKILL.md, and no Scripts & Assets section), it is a Medium `scripts-assets` gap, as in naive mode §2.7; §6 records it from that file.
128
158
 
129
159
  ### 5. Contextual Mode: Check Integration Pattern Completeness
130
160
 
131
161
  For stack skills, verify integration patterns are complete:
132
162
 
133
- - **All documented integration points have corresponding code examples**
163
+ - **All documented integration points carry the wiring evidence of the stack's mode** (defined below; a fenced code example is not required)
134
164
  - **Shared types are consistently used across referenced components**
135
165
  - **Middleware/plugin chains show complete flow, not fragments**
136
166
  - **Event handlers reference valid event types**
137
167
 
138
- Build integration completeness findings:
168
+ **Integration points.** Each Cross-Cutting Patterns entry and each Library Pair Integrations entry in the stack's Integration Patterns section is one integration point, and `patterns_documented` counts them. The Hub Library Connections list that create-stack-skill adds after them only summarizes each hub library's partners, so its bullets are not integration points: this section does not score them and `patterns_documented` does not count them.
169
+
170
+ **Wiring evidence (first criterion).** create-stack-skill gives an integration entry no slot for a code example: the entry records a type, the wiring evidence of the stack's mode and a confidence label, so the first criterion reads that evidence. Take the stack's mode from the Confidence labels of its integration entries: the stack is compose-mode when any of them carries the `[composed]` marker (alone or extended, as in `[composed, +T2 annotations]`) or `[inferred from shared domain]`, the markers create-stack-skill puts on every compose-mode integration; otherwise it is code-mode. An integration point meets the first criterion when its entry carries the evidence of its stack's mode:
171
+
172
+ - **Code mode:** at least one `file:line` citation (a source file path with a line number) where the libraries connect in the codebase, and, for a library-pair entry, a `**Key files:**` line that names at least one file.
173
+ - **Compose mode:** one `[from skill: {skill name}]` line for each constituent skill the entry joins, citing something that skill exports. For a skill that exports functions, that is an exported function signature, the `[from skill: {skill name}] {exported_function_signature}` line of the Integration Evidence Format in `skf-create-stack-skill/references/compose-mode-rules.md`. For any other constituent (a skill whose `scope_type` is `reference-app` or `docs-only`, or whose exports are not functions), it is the export, pattern surface or documented contract the line quotes. A `[from skill: …]` line that cites nothing the skill exports does not count.
174
+
175
+ A fenced code block is not required in either mode: an entry that carries its mode's evidence meets the criterion without one, and a code block does not stand in for missing evidence. When an entry fails the first criterion, name the missing evidence in its `incomplete_patterns` issue, for example `no file:line citation` or `no [from skill: …] line for {skill name}`.
176
+
177
+ Build integration completeness findings, and save them to `{run_dir}/integration.json` with the Write tool (§5c reads the file):
139
178
 
140
179
  ```json
141
180
  {
@@ -151,7 +190,9 @@ Build integration completeness findings:
151
190
  }
152
191
  ```
153
192
 
154
- **Zero integration patterns:** If no integration patterns are documented in SKILL.md (e.g., a contextual-mode skill that uses shared types but has no middleware chains, plugin hooks, or event flows): record `patterns_documented: 0`, `patterns_complete: 0`. The coherence score will use reference validity alone — see `{scoringRulesFile}` Coherence Score Aggregation: "If no integration patterns exist, combined coherence equals reference validity."
193
+ Each `incomplete_patterns` entry is an incomplete integration pattern, a Medium `integration-pattern` gap, with its Source at `SKILL.md:{line}` and the missing evidence as its Issue; §6 records it.
194
+
195
+ **Zero integration patterns:** If no integration patterns are documented in SKILL.md (e.g., a contextual-mode skill that uses shared types but has no middleware chains, plugin hooks, or event flows): record `patterns_documented: 0`, `patterns_complete: 0`. The coherence score then uses reference validity alone: with no integration patterns, §5c's script makes combined coherence equal reference validity.
155
196
 
156
197
  ### 5b. Migration/Deprecation Verification (Contextual Path)
157
198
 
@@ -161,24 +202,55 @@ results.
161
202
 
162
203
  ### 5c. Calculate Coherence Scores
163
204
 
164
- **Contextual mode only.** The reference-validity ratio, the integration-completeness ratio, and their fixed 0.6 / 0.4 weighted mean are pure arithmetic — the judgment (which references are valid in §4, which patterns are complete in §5) has already happened. Do not compute these percentages by hand; they are aggregated by `{coherenceAggregationScript}` (the formulas it encodes are documented in `{scoringRulesFile}` — Coherence Score Aggregation).
205
+ **Contextual mode only.** The reference-validity ratio, the integration-completeness ratio, and their weighted mean are pure arithmetic: the judgment (which references are valid in §4, which patterns are complete in §5) has already happened. Do not compute these percentages by hand; `{coherenceAggregationScript}` aggregates them and is the one home of the formula and its weights.
165
206
 
166
- Tally the counts from the §4 per-reference JSON (`valid_references` = references with `target_exists && type_match && signature_match && no issues`; `total_references` = references extracted in §3) and the §5 integration JSON (`patterns_documented`, `patterns_complete`), then invoke:
207
+ The script counts the references itself, from the per-reference files of §3 and §4, and reads the pattern counts from the §5 file:
167
208
 
168
209
  ```bash
169
- echo '{"valid_references": <V>, "total_references": <T>, "patterns_documented": <PD>, "patterns_complete": <PC>}' | uv run {coherenceAggregationScript} --stdin
210
+ uv run {coherenceAggregationScript} --references "{run_dir}/references.json" [--judged "{run_dir}/judged-references.json"] --integration "{run_dir}/integration.json" --output "{run_dir}/coherence.json"
170
211
  ```
171
212
 
172
- The script also accepts the JSON as a positional argument or via `--json-input`. Parse its output and read:
173
- - `referenceValidity` — reference-validity percentage
174
- - `integrationCompleteness` — integration-completeness percentage (`null` when no patterns are documented)
175
- - `combinedCoherence` — the combined coherence percentage passed to score.md §3a as the `coherence` input
213
+ Exit 2 (`INVALID_INPUT`): a file does not hold the shape §3 to §5 describe; correct it (re-dispatch the §4 subagent once for its file) and run the command again. Exit 1: a file is missing or is not JSON; write it again. A second failure: HALT with its `error` (`halt_reason: "helper-failed"`, phase `coherence-check:aggregate`).
214
+
215
+ `--output` also writes the result to the run folder, where step 5 hands it to the scoring script. Parse its output and read:
216
+ - `referenceValidity`: reference-validity percentage
217
+ - `integrationCompleteness`: integration-completeness percentage (`null` when no patterns are documented)
218
+ - `combinedCoherence`: the combined coherence percentage, the `coherence` score step 5 reads from `{run_dir}/coherence.json`
219
+
220
+ The script handles both edge cases the formula requires: `patterns_documented == 0` → `combinedCoherence` equals `referenceValidity` (no divide-by-zero); `total_references == 0` → `referenceValidity` is 100.0 (no references means no broken references). These values fill the `{percentage}%` placeholders in the output template loaded in Section 6. Its `invalidReferences[]` lists each invalid reference with its `status`, which §6 records.
221
+
222
+ ### 6. Write the Coherence Analysis Section
176
223
 
177
- The script handles both edge cases the formula requires: `patterns_documented == 0` → `combinedCoherence` equals `referenceValidity` (no divide-by-zero); `total_references == 0` → `referenceValidity` is 100.0 (no references means no broken references). These values fill the `{percentage}%` placeholders in the output template loaded in Section 6.
224
+ Load `{outputFormatsFile}` and use the appropriate Coherence Analysis section format (naive or contextual) to write the findings in place of the template's `## Coherence Analysis` heading and the placeholder comment under it, in `{outputFile}`.
225
+
226
+ Then record every coherence gap in the gap ledger `{ledgerFile}`: the hard gate (step 4c) decides from it, and the report step renders the Gap Report from it. `{gapLedgerScript}` (it resolves relative to the skill root) writes the record of each gap a script found from that script's file, with the severity and category the Gap Severity table gives it and a fixed title, Source and Remediation. Run the commands of this run's mode:
227
+
228
+ - **Naive mode:** the §2.1, §2.2 and §2.5 findings are High `structural` gaps and the §2.3, §2.4 and §2.6 findings Medium `structural` gaps; the §2.7 finding is a Medium `scripts-assets` gap. The scan files give all but §2.5's, with one `--served` for each family §2.1 found served by another heading:
229
+
230
+ ```bash
231
+ uv run {gapLedgerScript} append --ledger "{ledgerFile}" --stage coherence-check --from structure --input "{run_dir}/required-sections.json" --input "{run_dir}/structure.json" --input "{run_dir}/usage-scope.json" [--served <family>]...
232
+ ```
233
+
234
+ - **Contextual mode:** each §5c `invalidReferences[]` entry by its `status` (`missing` is a Critical `broken-reference` gap, a missing `scripts/` or `assets/` file included; `inaccurate` a High `inaccurate-reference` gap; `escapes` a High `reference-escape` gap) and the §4 scripts/assets gap:
235
+
236
+ ```bash
237
+ uv run {gapLedgerScript} append --ledger "{ledgerFile}" --stage coherence-check --from coherence --input "{run_dir}/coherence.json"
238
+ uv run {gapLedgerScript} append --ledger "{ledgerFile}" --stage coherence-check --from structure --input "{run_dir}/references.json"
239
+ ```
240
+
241
+ Then write the records no script wrote, each in the Ledger Record Format of `{outputFormatsFile}`: the §2.5 findings, titled with their `naive-coherence:` text and with their Source at `SKILL.md:{line}`; each §5 incomplete integration pattern; and in both modes a §2b / §5b migration section finding (Case 1 and Case 3 are Medium `migration-section` gaps, a Low `migration-section` gap when the reviewer downgraded Case 3 with an inline justification, and Case 2 is an Info `migration-section` gap). The split-body rows of the Reference Consistency table are not recorded here: coverage-check §1b recorded them. Write them as one JSON array on the lines between the two markers, exactly as they are: the quoted marker hands them to the script unchanged, quotes, apostrophes and `$` included. Run the command even when the array is empty (`[]`): the hard gate refuses to decide until every stage before it has recorded, with gaps or without.
242
+
243
+ ```bash
244
+ uv run {gapLedgerScript} append --ledger "{ledgerFile}" --stage coherence-check <<'SKF_GAPS'
245
+ <the records, one JSON array>
246
+ SKF_GAPS
247
+ ```
178
248
 
179
- ### 6. Append Coherence Analysis to Output
249
+ Rely on the JSON of each command:
180
250
 
181
- Load `{outputFormatsFile}` and use the appropriate Coherence Analysis section format (naive or contextual) to append findings to `{outputFile}`.
251
+ - Exit 0: the records are in the ledger. `appended` names the id each new record received, and `duplicates` the ones a rerun of this step had already recorded.
252
+ - Exit 2 (`INVALID_RECORD` or `INVALID_INPUT`): nothing was written. Correct each record `errors[]` names (its `index` counts from 0), or the file or flag the `error` names, and run the command again.
253
+ - Exit 1: HALT with the script's `error` (`halt_reason: "helper-failed"`, phase `coherence-check:ledger`).
182
254
 
183
255
  ### 7. Report Coherence Results
184
256
 
@@ -187,5 +259,5 @@ Report the coherence result to the user, then proceed to external validation:
187
259
  - **Naive mode:** the count of structural issues found (the coherence category is not scored — its weight redistributes to coverage).
188
260
  - **Contextual mode:** the reference-validity ratio, the integration-completeness ratio, the combined coherence percentage, and the issue count — full details are in the Coherence Analysis section.
189
261
 
190
- Update stepsCompleted, then load and execute {nextStepFile}.
262
+ Append `'coherence-check'` to `stepsCompleted` in the `{outputFile}` frontmatter, then load and execute {nextStepFile}.
191
263
 
@@ -0,0 +1,35 @@
1
+ # Coverage Check: Tier Branches
2
+
3
+ Load this file only from coverage-check.md §2, and follow the one section §2 names: **Quick Tier** at Quick tier, **Fallback Per-File Scan** when the Forge-tier recipe runner cannot be used. coverage-check.md's frontmatter bindings, its run files, its per-file results and its §2 **Exits** apply here unchanged. When the section is done, continue in coverage-check.md §2 after the tier that loaded it (at Deep tier, its extra checks; otherwise States 2 to 4 and then §2b).
4
+
5
+ ## Quick Tier
6
+
7
+ - **A skill quick-skill built** (`metadata.json` `generated_by` is `quick-skill`), **from local source** (State 1): quick-skill built its export list with `{extractPublicApiHelper}` `--mode quick`, so parse the entry points with the same parser and both sides count one surface. Resolve it ← first existing path in `{extractPublicApiProbeOrder}` and run it once per package in scope, with its manifest and one `--entry-file` for each entry-point file the Source API Surface Definition makes its surface, each path relative to `{source_path}` (`<n>` counts the packages from 1):
8
+
9
+ ```bash
10
+ uv run {extractPublicApiHelper} --mode quick --language <language> --source-root "{source_path}" --manifest-file <manifest path> --entry-file <entry path> > "{run_dir}/quick-<n>.json"
11
+ ```
12
+
13
+ Its `warnings` name each statement whose names the entry file alone cannot give. Read by eye only the statements its warnings name, save the names they give as a per-file result for the entry file that holds the statement, `{"file": "<entry path>", "exports_found": [<each name>], "signature_mismatches": []}`, and list those names in the Coverage Analysis section as read by eye. Give `surface` one `--quick` per package, one `--per-file` per saved result, the brief when the skill has one (its globs give the `scope.include` and `tier_a_include` sets), the metadata and, when init.md §2 bound one, the provenance map (the baselines of the §2b candidates and guards; they add no name):
14
+
15
+ ```bash
16
+ uv run {coverageInputsScript} surface --quick "{run_dir}/quick-<n>.json" [--per-file "{run_dir}/per-file-<n>.json"] [--brief "{forge_data_folder}/{skill_name}/skill-brief.yaml"] --metadata "{resolved_skill_package}/metadata.json" [--provenance "{forge_provenance_map}"] --output "{run_dir}/surface.json"
17
+ ```
18
+
19
+ - **Any other skill** (create-skill's Quick tier reads the entry points as source text), a source that is not local, or a helper that does not resolve or exits non-zero (it exits 1 on a language it does not parse): identify the exports by reading the entry points per the Source API Surface Definition, save one per-file result per entry file, run the `surface` command above with no `--quick`, and note in the Coverage Analysis section that the Quick-tier scan read them by eye.
20
+
21
+ ## Fallback Per-File Scan
22
+
23
+ The recipe runner cannot be used, so subagents read the files in scope one at a time. List every documented signature first: `plan` without `--surface` writes the map as `documentedSignatures`:
24
+
25
+ ```bash
26
+ uv run {scoreSignaturesScript} plan --inventory "{run_dir}/inventory.json" --output "{run_dir}/signature-plan.json"
27
+ ```
28
+
29
+ For each source file that defines public API exports, delegate a subagent that gets that map with the file. It extracts the file's exported symbols with their full signatures with ast-grep (or reads the file when `extraction.fallback.reason` says no ast-grep can run; list those files in the Coverage Analysis section as read by eye), compares each with the map's entry (params, return type), gives each mismatch the `line` that defines the export, and returns only `{"file", "exports_found": [...], "types_found": [<the exported interfaces, type aliases, enums and classes>], "signature_mismatches": [...]}`, each mismatch in the shape §2's signature comparison returns. Save each response to `{run_dir}/per-file-<n>.txt` with the Write tool and build the surface from them, one `--per-file` each, with the same baselines as at Quick tier:
30
+
31
+ ```bash
32
+ uv run {coverageInputsScript} surface --per-file "{run_dir}/per-file-<n>.txt" [--brief "{forge_data_folder}/{skill_name}/skill-brief.yaml"] --metadata "{resolved_skill_package}/metadata.json" [--provenance "{forge_provenance_map}"] --output "{run_dir}/surface.json"
33
+ ```
34
+
35
+ coverage-check.md §2b scores these responses once it has picked the denominator set.