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,13 +10,11 @@ Reference document for invoking `skf-shape-detect.py` — the shared shape class
10
10
 
11
11
  ## Invocation Contract
12
12
 
13
- **Resolve `{shapeDetectHelper}`** from `{shapeDetectProbeOrder}`; first existing path wins; HALT if neither resolves.
13
+ **Resolve `{shapeDetectHelper}`** from `{shapeDetectProbeOrder}`; first existing path wins. If neither resolves, step-auto-scope.md §3 HARD HALTs with exit code 3 (`resolution-failure`).
14
14
 
15
- **Command:**
16
- ```
17
- uv run {shapeDetectHelper} --repo-url <url> \
18
- --manifests <path1,path2,...> \
19
- --grammar-files <g1,g2,...> --tree-paths <d1/,d2/,file,...>
15
+ **Command** (step-auto-scope.md §3 runs it on the manifest scan and the file list §2 wrote to `{run_dir}/manifests-1.json` and `{run_dir}/tree.txt`):
16
+ ```bash
17
+ uv run {shapeDetectHelper} --repo-url "<url>" --manifests-file "{run_dir}/manifests-1.json" --manifest-dir "{scan_root}" --tree-file "{run_dir}/tree.txt"
20
18
  ```
21
19
 
22
20
  **Arguments:**
@@ -24,9 +22,11 @@ uv run {shapeDetectHelper} --repo-url <url> \
24
22
  | Arg | Required | Description |
25
23
  |-----|----------|-------------|
26
24
  | `--repo-url` | Yes | Repository URL (context only — no cloning performed) |
27
- | `--manifests` | Yes | Comma-separated local file paths to manifest files (may be empty when a tree-level signal carries the classification) |
28
- | `--grammar-files` | No | Comma-separated repo-relative grammar files (`*.y`, `*.g4`, `*.pest`, `Grammar/python.gram`, ...) — a whole-language signal |
29
- | `--tree-paths` | No | Comma-separated repo-relative directory (trailing `/`) and structural file signals harvested from the clone (a `compiler/` dir, a lexer+parser+ast triad) |
25
+ | `--manifests-file` | One of the two | The JSON envelope `skf-scan-manifests.py scan` printed: the script keeps the manifest types it classifies (the supported manifests below) and resolves each `path` against `--manifest-dir`, so no caller filters, resolves or joins the list |
26
+ | `--manifest-dir` | With `--manifests-file` | The folder the scan ran on, the scan root |
27
+ | `--manifests` | One of the two | Comma-separated local file paths to manifest files, in place of `--manifests-file` (may be empty when a tree-level signal carries the classification) |
28
+ | `--tree-file` | No | The repository's whole file list, one path per line (`git ls-tree -r --name-only HEAD`, `git ls-files` or `find` output) or JSON. The script finds the tree-level signals in it itself (grammar files such as `*.y`, `*.g4`, `Grammar/python.gram` or a root `grammar.js`; a `compiler/` folder or a lexer+parser+ast triad), with its own gates, so no caller filters the list first |
29
+ | `--grammar-files`, `--tree-paths` | No | The older way to pass the same signals, harvested by the caller; not with `--tree-file` |
30
30
 
31
31
  **Supported manifests:** `package.json`, `pyproject.toml`, `Cargo.toml`, `go.mod`, `pom.xml`, `build.gradle`, `build.gradle.kts`, `Package.swift`
32
32
 
@@ -47,7 +47,7 @@ JSON object on stdout:
47
47
  | Code | Meaning | Consumer Action |
48
48
  |------|---------|-----------------|
49
49
  | 0 | Shape classified (not unknown) | Use shape result for scope mapping |
50
- | 1 | Unknown shape (no heuristic matched) | Fall back to interactive mode |
50
+ | 1 | Unknown shape (no heuristic matched) | Fall back to interactive mode: set the report's `mode: 'interactive'` first, so a resumed session takes the interactive chain |
51
51
  | 2 | Error (invalid args, missing/unreadable files, parse failure) | HARD HALT with `resolution-failure` |
52
52
 
53
53
  On exit code 2, error details are written to stderr as JSON: `{"error": "message", "code": "ERROR_CODE"}`
@@ -59,7 +59,9 @@ On exit code 2, error details are written to stderr as JSON: `{"error": "message
59
59
  | `library-API` | `full-library` | export_count ≤ 200 |
60
60
  | `library-API` | `public-api` | export_count > 200 (surface too large for full coverage) |
61
61
  | `reference-app` | `reference-app` | Direct mapping — apps, CLIs, demos |
62
- | `language-reference` | `full-library` | Language tools/parsers are library-shaped from a skill perspective. **Corpora-dependent** for a *whole-language* reference (a `grammar_file:`/`tree_triad:` signal — a compiler/interpreter): its value is the language's prose (guide/Book + std/library docs), not compiler internals, so step-auto-scope.md §6b seeds companion corpora and §6/§7 record an honest DEGRADED caveat when none are found (mirrors the §3b facet-coverage guard). A parser *library* (`parser_producer:`/`parser_dep:`) is exempt — its code is the product. |
62
+ | `reference-app` with an `app_or_library:framework_dep` signal | `reference-app`, or the `library-API` mapping | The only app signal is a framework dependency, which a library that extends the framework declares too. An application or demo built on the framework stays `reference-app`; a library that extends or wraps the framework takes the `library-API` mapping (`full-library` or `public-api` by `export_count`). step-auto-scope.md §4 judges which |
63
+ | Any shape with a `language_or_user:parser_dep` signal | That shape's mapping, or `language-reference`'s | A parser library among the runtime dependencies (`parser_dep:`) fits a language built on it and a project that only reads its input with it alike. A repository that implements a language, DSL, query language or grammar on it (a compiler, an interpreter, a rule or template engine) takes `language-reference`; one that parses a data format, a config file, command-line text or source code in existing languages with it (an editor, a linter, code search or an indexer) keeps its shape. step-auto-scope.md §4 judges which |
64
+ | `language-reference` | `full-library` | Language tools/parsers are library-shaped from a skill perspective. **Corpora-dependent** for a *whole-language* reference (a `grammar_file:`/`tree_triad:` signal: a compiler/interpreter): its value is the language's prose (guide/Book + std/library docs), not compiler internals, so step-auto-scope-corpora.md, which step-auto-scope.md §6 loads for that signal, seeds companion corpora, and §6/§7 record an honest DEGRADED caveat when none are found (mirrors the §3b facet-coverage guard). A parser library, or a language built on one (`parser_producer:`/`parser_dep:`), is exempt: no `grammar_file:` or `tree_triad:` signal, so §6 seeds no corpora. |
63
65
  | `stack-compose` | `full-library` | Decomposition candidate when `package_count > 3` — cohesion-checked in step-auto-scope.md §3b |
64
66
  | `unknown` | N/A | Triggers fallback to interactive mode |
65
67
 
@@ -79,7 +81,7 @@ When neither threshold is met, the single-scope flow proceeds unchanged.
79
81
 
80
82
  The five-shape heuristic ladder applies in order (first match wins):
81
83
 
82
- 1. **language-reference** — parser/grammar/language-toolchain project. Signals, strongest first: a hand-written-compiler tree structure (a dedicated `compiler/` directory with a lexer+parser+ast triad plus a codegen/VM/type-checker member — catches rustc, TypeScript, Go); a declared grammar file (`Grammar/python.gram`, a root `parse.y`, a `*.g4` — catches CPython, Ruby); the repo's own name being a known parser/grammar tool (pest, lalrpop, lark — the producer); or a parser-generator dependency (a DSL built on antlr4/lalrpop — the consumer). Delegating consumers (formatters, linters, bundlers that depend on a parser) and markup/DSL parsers (CSS, markdown, GraphQL) are excluded.
84
+ 1. **language-reference**: parser/grammar/language-toolchain project. Signals, strongest first: a hand-written-compiler tree structure (a dedicated `compiler/` directory with a lexer+parser+ast triad plus a codegen/VM/type-checker member, as in rustc, TypeScript, Go); a declared grammar file (`Grammar/python.gram`, a root `parse.y`, a `*.g4`, as in CPython, Ruby); or the repo's own name being a known parser/grammar tool (pest, lalrpop, lark: the producer). A parser library among the core members' runtime dependencies (the consumer) decides only when no rung below answers and no manifest declares a bin (a bare DSL manifest); otherwise the shape that answers carries the `language_or_user:parser_dep` question. Delegating consumers (formatters, linters, bundlers that depend on a parser) and markup/DSL parsers (CSS, markdown, GraphQL) are excluded.
83
85
  2. **stack-compose** — multi-ecosystem composite project. Signals: manifests from 2+ distinct ecosystems
84
86
  3. **reference-app** — application, CLI, or demo project. Signals: npm `bin` field, Rust `[[bin]]`, framework deps (next, fastapi, axum, etc.)
85
87
  4. **library-API** — library exposing a programmatic API. Signals: `main`/`module`/`exports` fields, `[lib]` target, export count
@@ -36,6 +36,12 @@ Rules for identifying discrete skillable units within a project. A "skillable un
36
36
  | Comment boundaries | Code comments marking sections | `// --- Auth Module ---` |
37
37
  | Import clustering | Files that import primarily from each other | Tight import graph cluster |
38
38
 
39
+ `skf-disqualify-candidates.py` reports the signals a boundary's file list shows, in each record's `signals` (identify-units §2): an independent manifest (`own_manifest`), a separate entry point (`entry_point`), a Docker/service definition (`service_definition`), README.md presence (`readme`), a separate test suite (`test_suite`), a CI/CD pipeline reference (`ci_reference`) and a large directory (`large_directory`). Workspace membership is reported too, as each candidate's `workspace_member` (**Candidate Boundaries**): scan-project passes the scan the workspaces `skf-detect-workspaces.py --snapshot` resolves from the workspace configuration, and a path discover-additional-source adds has none (null). The other signals are judged from the code.
40
+
41
+ ## Candidate Boundaries
42
+
43
+ The boundaries scan-project and discover-additional-source propose for a project path, which identify-units then classifies, are the `candidates[]` of its `skf-scan-manifests.py` scan, which applies the rule itself: the folders that hold a manifest or a Docker, compose or serverless file, less a workspace root with no code of its own (`.` is the scan root). Name a candidate by its folder.
44
+
39
45
  ## Boundary Classification
40
46
 
41
47
  ### Service Boundary
@@ -72,71 +78,60 @@ Rules for identifying discrete skillable units within a project. A "skillable un
72
78
 
73
79
  ### Composite Boundary
74
80
  - Two or more Package or Module boundaries that only deliver value together (no constituent is independently useful to the skill consumer)
75
- - Hard cross-boundary dependency: constituents share types, traits, or interfaces that are not re-exported through a single barrel — consumers must import from multiple constituents to use the integration
76
- - Common pattern: a set of crates/packages in the same repo that implement a protocol together (e.g., plugin crates for a framework, verification + encoding halves of a cryptographic library)
81
+ - Hard cross-boundary dependency: consumers use the constituents together, through types, traits or interfaces they share, or through one facade that re-exports them all
82
+ - Common pattern: a set of crates/packages in the same repo that implement a protocol together (e.g., plugin crates for a framework, verification + encoding halves of a cryptographic library), or a facade package over its sub-packages
77
83
  - Scope type: inherits from the dominant constituent (typically `full-library` or `specific-modules`)
78
84
 
79
- **Detection heuristic (apply after initial classification, before user confirmation):**
80
- 1. Among the qualifying units, find groups of ≥2 boundaries where either:
81
- - **Mutual hard dependency:** Every constituent imports from at least one other constituent in the group, AND no constituent's public API is self-contained (removing any one breaks the others)
85
+ **Detection heuristic (map-and-detect §5, once the import graph and the integration map exist):**
86
+ 1. Among the qualifying units, find groups of ≥2 boundaries where any trigger holds:
87
+ - **Mutual hard dependency:** the constituents import each other in a cycle (`skf-find-cycles.py` over the `skf-count-imports.py` edges), AND no constituent's public API is self-contained (removing any one breaks the others)
82
88
  - **Shared integration surface:** Constituents share types/traits defined in one constituent but consumed by all others, AND the consuming constituents have no independent barrel (their value depends on the shared definitions)
89
+ - Any of the **Cohesion Triggers** below
83
90
  2. For each detected group, propose merging into a single composite unit:
84
- - Name: `{common-prefix}` or `{integration-name}` (derive from shared namespace or repo name)
91
+ - Name: by the Unit Names rule below, for a merged unit
85
92
  - Constituents: list of merged boundary names and paths
86
- - Rationale: which heuristic triggered (mutual hard dependency or shared integration surface)
87
- 3. The merge is a **recommendation** — present to user for confirmation in identify-units §3b
93
+ - Rationale: which trigger fired, with its evidence
94
+ 3. The merge is a **recommendation**: the user confirms it in map-and-detect §6, and a headless run accepts it. A group that merges is not also a stack skill candidate.
95
+
96
+ ### Cohesion Triggers
97
+
98
+ The one statement of when a monorepo's members belong in one cohesive skill rather than one skill per package. The `[auto]` path (step-auto-scope §3b) and the interactive chain (map-and-detect §5, and discover-additional-source for a path [D] adds) apply it. Empirically, 5/5 real monorepos (animato 15 crates, trpc, react 38 packages, aws-sdk-js-v3 442 packages, plus zod) were best served as one cohesive skill or a curated few, not one skill per package. The evidence comes from the `skf-scan-manifests.py` scan (`umbrella_candidates[]`, and each member's `name`, `private` and `internal_deps`), never from opening each member manifest.
99
+
100
+ Merge when **any** of these holds:
101
+
102
+ - **Umbrella facade:** one package re-exports the members: a root or named package whose dependencies include the other workspace members (an `umbrella_candidates[]` entry, with the members its `internal_deps` cover), or which `pub use` / `export *`s them. The facade *is* the public surface (e.g. animato's `crates/animato` re-exporting its 15 sub-crates).
103
+ - **Shared runtime contract:** the members are consumed together through one entry point, and teaching the shared invariant covers them (e.g. tRPC's adapters around `@trpc/server`; aws-sdk's `new XClient(...) → client.send(new YCommand(...))` shared by every `@aws-sdk/client-*`).
104
+ - **Internal building blocks:** the members are private/internal pieces of one product, not independently meaningful to a consumer (`private: true` on the members).
105
+
106
+ Split instead when the members are **independently published with distinct public surfaces serving different concerns**, **and no umbrella re-exports them**: e.g. `react-dom` and `react-server-dom-*` are separate installs with separate jobs, or a federated SDK where a consumer only ever wants one service. Each genuinely distinct facet earns its own skill.
88
107
 
89
108
  ## Disqualification Rules
90
109
 
91
110
  Do not recommend a boundary as a skillable unit when:
92
111
 
93
- 1. **Too small**: Fewer than 3 source files or 100 lines of code
94
- 2. **Generated code**: Auto-generated files (protobuf, GraphQL codegen, etc.)
112
+ 1. **Too small**: Fewer than 3 source files or 100 lines of code. `skf-disqualify-candidates.py` counts the source files that are not generated: lockfiles, documentation, data and configuration files, manifests and build tool files (`setup.py`, `build.gradle`, `gradlew`, `vite.config.ts` and the like) are not source files
113
+ 2. **Generated code**: every source file is generated (protobuf, GraphQL codegen, etc.): under a vendored or cache folder (`node_modules/`, `vendor/`, `__pycache__/` and the like) at any depth, under a build output folder (`dist/`, `build/`, `target/`) directly below the unit or beside a manifest, or opening with a generated-code header such as `@generated`. A source folder of an output folder's name further down (`src/build/`, the Java package folder `com/acme/build/`) is the unit's own code. A boundary with only some generated files stays, with those files left out of its counts, and identify-units judges it
95
114
  3. **Pure configuration**: Only config files with no logic
96
115
  4. **Test-only**: Test utilities with no production code
97
116
  5. **Vendor/dependency**: Third-party code copied into project
98
117
  6. **Already skilled**: Existing skill found in forge_data_folder (recommend update-skill instead)
99
118
 
100
- ## Script/Asset Detection Signals
101
-
102
- During per-unit analysis, check for scripts and assets alongside code exports.
103
-
104
- **Script signals:**
119
+ ## Unit Names
105
120
 
106
- | Strength | Signal | Example |
107
- |----------|-----------------------------------------------------------------------------------------------|-----------------------------------------------------|
108
- | Strong | Entry point in `package.json` `bin`, Cargo.toml `[[bin]]`, pyproject.toml `[project.scripts]` | `"bin": { "migrate": "scripts/migrate.js" }` |
109
- | Strong | Shebang + executable file | `#!/usr/bin/env python` in `scripts/setup.py` |
110
- | Moderate | File in `scripts/`, `bin/`, `tools/`, `cli/` directory | `scripts/validate.sh` |
111
- | Moderate | CI/CD reference to script | `.github/workflows/test.yml` runs `scripts/test.sh` |
121
+ Every unit, composite and brief is named by `skf-skill-inventory.py derive-name`, from the same inputs on the `[auto]` path (step-auto-scope §6 and its split branch) and the interactive chain (identify-units §2, map-and-detect §5, discover-additional-source), so one unit gets one name on both:
112
122
 
113
- **Asset signals:**
123
+ - **A single unit** passes its own manifest's `name` and `private` flag. A private manifest names nothing, so a monorepo's workspace root or an internal app takes its folder's or repository's name; a published package takes its manifest's (`@trpc/server` gives `trpc-server`).
124
+ - **A merged unit** (a composite, or a monorepo the cohesion check merges) passes the facade's manifest name when the umbrella facade trigger fired, and its members' manifest names: a composite's constituents, a merged monorepo's published members (its private examples and tools left out). Without a facade it takes the name the members share (`trpc` for `@trpc/server` and `@trpc/client`), else the repository's.
114
125
 
115
- | Strength | Signal | Example |
116
- |----------|--------------------------------------------------------------------------------|----------------------------------|
117
- | Strong | JSON Schema file with `$schema` key | `schemas/config.schema.json` |
118
- | Strong | Config template with `.example` or `.template` extension | `config.yaml.example` |
119
- | Moderate | File in `assets/`, `templates/`, `schemas/`, `configs/`, `examples/` directory | `templates/report.hbs` |
120
- | Moderate | OpenAPI/GraphQL definition | `openapi.json`, `schema.graphql` |
121
-
122
- **Per-unit output:** Record `has_scripts: boolean`, `has_assets: boolean`, `script_files: string[]`, `asset_files: string[]`.
123
-
124
- **Disqualify:** Generated files (dist/, build/), vendored dependencies, IDE configs (.vscode/, .idea/), binary files (.so, .dll, .jar).
126
+ Names that would clash in one call are told apart by their parent folders (`server-api`, `client-api`).
125
127
 
126
128
  ## Stack Skill Candidate Detection
127
129
 
128
- Flag units as stack skill candidates when:
130
+ Flag units as stack skill candidates when (map-and-detect §5, in the same pass as the composite merges):
129
131
 
130
- 1. **Co-import frequency**: Two or more units are imported together in 3+ files
132
+ 1. **Co-import frequency**: Two or more units are imported together in 3+ files (a `skf-pair-intersect.py` pair over the `skf-count-imports.py` importer lists with an `intersection_count` of 3 or more)
131
133
  2. **Integration adapter**: A unit exists primarily to bridge two other units
132
134
  3. **Shared state**: Multiple units read/write to the same data store
133
135
  4. **Orchestration layer**: A unit coordinates calls across multiple other units
134
136
 
135
- ## Tier-Aware Scanning Depth
136
-
137
- | Forge Tier | Scanning Approach |
138
- |------------|----------------------------------------------------------------------------------------------------|
139
- | Quick | File structure analysis: directory trees, manifest files, entry points, naming conventions |
140
- | Forge | AST analysis: export surfaces, import graphs, dependency trees, type hierarchies |
141
- | Forge+ | AST + CCC: semantic file pre-ranking before structural analysis, CCC signals for relevance scoring |
142
- | Deep | AST + QMD: temporal evolution, refactoring patterns, semantic relationships, architectural drift |
137
+ Stack skill candidates are useful separately and also together; units that only deliver value together are a Composite Boundary instead, never both.
@@ -7,16 +7,18 @@ description: Drift detection between skill and current source code. Use when the
7
7
 
8
8
  ## Overview
9
9
 
10
- Detects drift between an existing skill and its current source code, producing a severity-graded drift report with AST-backed findings and actionable remediation suggestions. Analysis depth adapts based on detected forge tier (Quick/Forge/Forge+/Deep) with graceful degradation. Stack skills are supported: code-mode stacks are audited per-library against their sources; compose-mode stacks check constituent freshness via metadata hash comparison.
10
+ Detects drift between a skill and its current source code and writes a severity-graded drift report with AST-backed findings and remediation suggestions; analysis depth follows the forge tier (Quick/Forge/Forge+/Deep). Stack skills: a compose-mode stack checks its constituents' freshness by metadata hash; a code-mode stack is diffed library by library. A docs-only skill is audited by its documents' hashes; a skill with no provenance map has no baseline, so step 1 stops it.
11
11
 
12
12
  ## Conventions
13
13
 
14
14
  - Bare paths (e.g. `references/<name>.md`) resolve from the skill root.
15
- - **Module-level path exception:** bare paths beginning with `knowledge/` or `shared/` resolve from the SKF module root (`{project-root}/_bmad/skf/` installed, `src/` in dev), not the skill root — stage files reference `knowledge/version-paths.md` and `knowledge/tool-resolution.md`, and the terminal step chains to `shared/health-check.md`.
16
- - `references/` holds prompt content carved out of SKILL.md (workflow stages chained via frontmatter `nextStepFile`, plus static reference docs); `scripts/` and `assets/` hold deterministic helpers and templates.
15
+ - **Module-level path exception:** bare paths beginning with `knowledge/` or `shared/` resolve from the SKF module root (`{project-root}/_bmad/skf/` installed, `src/` in dev), not the skill root.
16
+ - **Sibling skills:** a path that names another SKF skill's folder (`skf-<name>/...`) resolves from the SKF module root, and that skill must be installed with this one.
17
+ - `scripts/` holds `render-drift-tables.py`, which steps 3, 5 and 6 run to print their drift tables.
17
18
  - `{skill-root}` resolves to this skill's installed directory (where `customize.toml` lives, if present).
18
19
  - `{project-root}`-prefixed paths resolve from the project working directory.
19
20
  - `{skill-name}` resolves to the skill directory's basename.
21
+ - **Cross-skill data coupling:** `re-index.md` loads `extraction-patterns.md` and `tier-degradation-rules.md` from `skf-create-skill/references/`.
20
22
 
21
23
  ## Role
22
24
 
@@ -24,91 +26,81 @@ You are a skill auditor in Ferris Audit mode: a deterministic drift-detection wo
24
26
 
25
27
  ## Workflow Rules
26
28
 
27
- These rules apply to every step in this workflow:
28
-
29
29
  - Never fabricate findings — all data must trace to source code with file:line citations
30
30
  - Only load one step file at a time — never preload future steps
31
31
  - Update `stepsCompleted` in output file frontmatter before loading next step
32
32
  - Always communicate in `{communication_language}`
33
- - If `{headless_mode}` is true, auto-proceed through confirmation gates with their default action and log each auto-decision
33
+ - If `{headless_mode}` is true, auto-proceed through confirmation gates with their default action and log each auto-decision; step 1's gates (manifest-vs-link, upstream-drift, baseline confirm) also record theirs in the run sink as they decide
34
+ - Every HARD HALT names its exit code, `halt_reason` and phase; in headless mode it prints its envelope through the shared emitter, as each stage's **Halt envelope** paragraph shows
35
+ - Once the [C] of `references/upstream-checkout.md` has bound `{source_tree}` (the private tree it read the upstream ref into), every step reads the source there, never at the recorded `source_path`, and every HALT after it first runs `uv run {sourceTreeHelper} close --tree "{source_tree}"` from `{project-root}` and goes on whatever it prints
36
+ - Run state (the gates' decisions, the warnings, the emitter's payloads) lives in `{run_dir}`: step 6 deletes it, a HALT keeps it
34
37
 
35
38
  ## Stages
36
39
 
37
40
  | # | Step | File | Auto-proceed |
38
41
  |---|------|------|--------------|
39
- | 1 | Initialize & Baseline | references/init.md | No (confirm) |
42
+ | 1 | Initialize & Baseline | references/init.md | No (confirm on a doubt: tier below the compile tier, or provenance map over 90 days old) |
43
+ | 1b | Upstream Checkout (only when upstream moved) | references/upstream-checkout.md | No (Upstream-Drift Gate) |
44
+ | 1c | Constituent Freshness (compose-mode stacks only) | references/constituent-freshness.md | Yes |
40
45
  | 2 | Re-Index Source | references/re-index.md | Yes |
41
46
  | 3 | Structural Diff | references/structural-diff.md | Yes |
42
47
  | 4 | Semantic Diff | references/semantic-diff.md | Yes (skip at non-Deep) |
43
48
  | 5 | Severity Classification | references/severity-classify.md | Yes |
44
- | 5a | Doc Drift | references/step-doc-drift.md | Yes |
49
+ | 5a | Doc Drift | references/doc-drift.md | Yes |
45
50
  | 6 | Report | references/report.md | Yes |
46
51
  | 7 | Workflow Health Check | references/health-check.md | Yes |
47
52
 
53
+ Stage 1b returns to init.md at §5b's **Record for report**, then §6. Step 1 §4 picks stage 1c from the provenance map: it replaces stages 2 to 4 for a compose-mode stack, which has no source tree to re-index (init.md → constituent-freshness.md → severity-classify.md). A docs-only skill skips stages 2 to 4 too (step 1 §3): init.md → doc-drift.md → severity-classify.md → report.md.
54
+
48
55
  ## Invocation Contract
49
56
 
50
57
  | Aspect | Detail |
51
58
  |--------|--------|
52
- | **Inputs** | `skill_name` [required], `skill_path` [optional override — full path to skill directory; bypasses manifest/symlink resolution], `tier_override` [optional: Quick / Forge / Forge+ / Deep — overrides detected tier], `degraded` [optional bool — pre-confirm degraded-mode opt-in when no provenance map exists], `upstream_drift_choice` [optional: C / S / X — pre-supplied answer for the upstream-drift gate at init.md §5b], `dirty_worktree_choice` [optional: T / A / F — pre-supplied answer for the dirty-worktree sub-gate at init.md §5b], `force` [optional bool — when paired with `dirty_worktree_choice=F` or used for any future destructive-action gate, signals consent to skip the confirmation] |
53
- | **Gates** | step 1: Manifest-vs-Symlink Gate [N] · Upstream-Drift Gate [C/S/X] · Dirty-Worktree Sub-Gate [T/A/F] · Degraded-Mode Gate [D/X] · Baseline Confirm Gate [C] |
54
- | **Outputs** | `drift-report-{timestamp}.md` at `{forge_version}/` with `drift_score` and `nextWorkflow` frontmatter; per-run result contract at `{forge_version}/audit-skill-result-{timestamp}.json` plus `-latest.json` copy; final `SKF_AUDIT_RESULT_JSON` line on stdout when `{headless_mode}` is true |
55
- | **Headless** | All gates auto-resolve with default action when `{headless_mode}` is true; pre-supplied inputs (`upstream_drift_choice`, `dirty_worktree_choice`, `degraded`, `tier_override`) consumed at the gates that would otherwise prompt |
56
- | **Exit codes** | See "Exit Codes" below |
57
-
58
- ## Exit Codes
59
-
60
- Every hard halt in this workflow exits with a stable code so headless automators can branch on the failure class without grepping message text:
61
-
62
- | Code | Meaning | Raised by |
63
- | ---- | -------------------- | ------------------------------------------------------------------------------------------------------------------ |
64
- | 0 | success | step 7 (terminal health-check) |
65
- | 2 | input-missing | step 1 §1 — no `skill_name` supplied in headless mode (interactive prompt cannot resolve) |
66
- | 3 | resolution-failure | step 1 §1 (skill not found at resolved path: missing `SKILL.md`); step 1 §2 (`forge-tier.yaml` missing — setup-forge not run); step 1 §5 (source directory from provenance map no longer exists / inaccessible) |
67
- | 4 | write-failure | step 1 §6 / step 6 §3 (drift report write failed: read-only mount, disk full, permissions denied) |
68
- | 6 | user-cancelled | step 1 §1 manifest-vs-symlink gate `[X]` · step 1 §4 degraded-mode gate `[X]` · step 1 §5b upstream-drift gate `[X]` · step 1 §5b dirty-worktree sub-gate `[A]` (and `[A]` headless default) |
69
-
70
- ## Result Contract (Headless)
71
-
72
- When `{headless_mode}` is true, step 6 emits a single-line JSON envelope on **stdout** before chaining to step 7, and every hard halt emits the same envelope shape on **stderr** with `status: "error"`:
73
-
74
- ```
75
- SKF_AUDIT_RESULT_JSON: {"status":"success|error","skill_name":"…","drift_score":"CLEAN|MINOR|SIGNIFICANT|CRITICAL|null","report_path":"…|null","next_workflow":"update-skill|null","audit_ref":"…|null","exit_code":0,"halt_reason":null}
76
- ```
77
-
78
- `status` is `"success"` on the terminal happy path, `"error"` on any halt. `drift_score` is `null` when the workflow halted before severity classification ran. `next_workflow` is `"update-skill"` when CRITICAL or HIGH findings exist, otherwise `null`. `halt_reason` is one of: `null` (success), `"input-missing"`, `"skill-not-found"`, `"forge-tier-missing"`, `"source-dir-missing"`, `"write-failed"`, `"user-cancelled"`. `exit_code` matches the table above.
59
+ | **Inputs** | `skill_name` [required], `skill_path` [optional: the skill folder, bypassing manifest/symlink resolution], `tier_override` [optional: Quick / Forge / Forge+ / Deep, in place of the detected tier], `upstream_drift_choice` [optional: C / S / X; answers the upstream-drift gate in references/upstream-checkout.md; C, auditing the upstream ref from a private tree, when unset] |
60
+ | **Gates** | step 1: Manifest-vs-Symlink Gate [N/M/X] · Upstream-Drift Gate [C/S/X] (references/upstream-checkout.md, only when upstream moved) · Baseline Confirm Gate [C/X] (only on a doubt: the forge tier is below the compile tier, or the provenance map is more than 90 days old) |
61
+ | **Outputs** | The drift report, the JSON it was built from and the result contract, in `{forge_version}/` (the audited version's folder): `references/headless-contract.md` names each file |
62
+ | **Headless** | Every gate takes its default action, a pre-supplied `upstream_drift_choice` answers the upstream-drift gate, `tier_override` sets the tier (step 1 §2), and each gate's decision lands in the envelope's `headless_decisions` |
63
+ | **Exit codes** | `references/headless-contract.md`: each halt class's exit code and `halt_reason`, and the `SKF_AUDIT_RESULT_JSON` envelope |
79
64
 
80
65
  ## On Activation
81
66
 
82
67
  1. Load config from `{project-root}/_bmad/skf/config.yaml` and resolve:
83
68
  - `project_name`, `output_folder`, `user_name`, `communication_language`, `document_output_language`
84
69
  - `skills_output_folder`, `forge_data_folder`, `sidecar_path`
85
- - Generate and store `timestamp` as `YYYYMMDD-HHmmss` format. This value is fixed for the entire workflow run.
70
+ - `timestamp` ← now, as `YYYYMMDD-HHmmss`, fixed for the whole run
71
+ - `run_dir` ← `{project-root}/_bmad-output/.skf-run/skf-audit-skill-{timestamp}`, the run folder step 4 below creates
86
72
 
87
- 2. **Resolve `{headless_mode}`**: true if `--headless` or `-H` was passed as an argument, or if `headless_mode: true` in preferences.yaml. Default: false.
73
+ 2. **Resolve `{headless_mode}`**: true if `--headless` or `-H` was passed as an argument, or if `headless_mode: true` in `{sidecar_path}/preferences.yaml`. Default: false.
88
74
 
89
75
  3. **Resolve workflow customization.** Run:
90
76
 
91
77
  ```bash
92
- python3 {project-root}/_bmad/scripts/resolve_customization.py \
93
- --skill {skill-root} --key workflow
78
+ uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --project-root {project-root} --key workflow
94
79
  ```
95
80
 
96
- The script merges the three customization layers per `bmad-customize`'s structural merge rules (scalars override, arrays append):
81
+ It merges the bundled `{skill-root}/customize.toml` with `{project-root}/_bmad/custom/skf-audit-skill.toml` (team overrides, committed) and `.user.toml` (personal overrides, gitignored). When it exits non-zero, prints no JSON or is missing, print one line, `[activation/warn] customization_resolver_unavailable: <reason>` (`<reason>`: its first stderr line, `not found` when the script is missing, `no JSON` when it printed none). If the resolver cannot run, read `{skill-root}/customize.toml` alone and use its bundled defaults: the `{project-root}/_bmad/custom/` overrides do not apply to this run. Then keep the reason as `{customization_resolver_unavailable}`, which step 6 hands to the emitter as a warning.
82
+
83
+ Bind the two scalars the stages read, each to its bundled default when the merged value is empty or absent:
97
84
 
98
- - `{skill-root}/customize.toml` — bundled defaults
99
- - `_bmad/custom/<skill-name>.toml` under `{project-root}` — team overrides (committed)
100
- - `_bmad/custom/<skill-name>.user.toml` under `{project-root}` — personal overrides (gitignored)
85
+ - `{driftReportTemplatePath}` ← `workflow.drift_report_template_path`, else `assets/drift-report-template.md`
86
+ - `{onCompleteCommand}` ← `workflow.on_complete`, else empty (step 6 then runs no hook)
101
87
 
102
- If the script fails or is missing, fall back to reading `{skill-root}/customize.toml` directly — the bundled defaults are an empty string for each path scalar.
88
+ Run `workflow.activation_steps_prepend` now, treat `workflow.persistent_facts` as standing context for the run (a `file:` entry loads its file or glob contents as facts: the bundled default loads every `project-context.md` under `{project-root}`; an entry prefixed `!` drops each earlier entry it names and loads nothing itself, so an override's `"!file:{project-root}/**/project-context.md"` turns that default off), then run `workflow.activation_steps_append` once step 4 below has passed.
103
89
 
104
- Apply the path-scalar fallback now so stage files don't have to repeat the conditional logic. For each of the scalars, if the merged value is empty or absent, use the bundled default:
90
+ 4. **Pre-flight: `uv`, the helpers and the run folder.** Before the first prompt, resolve `{emitEnvelopeHelper}` ← `{project-root}/_bmad/skf/shared/scripts/skf-emit-result-envelope.py`, else `{project-root}/src/shared/scripts/skf-emit-result-envelope.py`. If neither exists, HALT (exit code 3, `halt_reason: "helper-missing"`) and display only: "Audit Skill cannot run without `skf-emit-result-envelope.py`, which is not installed. Re-install SKF."
105
91
 
106
- - `{driftReportTemplatePath}` ← `workflow.drift_report_template_path` if non-empty, else `assets/drift-report-template.md`
107
- - `{severityRulesPath}` ← `workflow.severity_rules_path` if non-empty, else `references/severity-rules.md`
108
- - `{onCompleteCommand}` ← `workflow.on_complete` if non-empty, else empty (no-op — report.md skips the hook invocation entirely)
92
+ Run `uv --version`, and check that `skf-load-provenance.py`, `skf-structural-diff.py`, `skf-severity-classify.py` and `skf-detect-docs.py` each exist in `{project-root}/_bmad/skf/shared/scripts/` or `{project-root}/src/shared/scripts/`. If `uv --version` fails, or a helper is in neither folder, HALT (exit code 3, `halt_reason: "helper-missing"`) at phase `on-activation:helpers`, naming what is missing: "Audit Skill cannot run without `<uv or the script>`, which is not installed. Install uv (<https://docs.astral.sh/uv/>) or re-install SKF, then re-run." Then create the run folder:
109
93
 
110
- Stash all three as workflow-context variables. Stage files reference `{driftReportTemplatePath}` / `{severityRulesPath}` / `{onCompleteCommand}` directly.
94
+ ```bash
95
+ mkdir -p "{project-root}/_bmad-output/.skf-run" && mkdir "{run_dir}"
96
+ ```
111
97
 
112
- Also apply the array surfaces (not silent no-ops): run `workflow.activation_steps_prepend` now, treat `workflow.persistent_facts` as standing context for the run (`file:`-prefixed entries load their file/glob contents as facts — the bundled default globs any `project-context.md`), then run `workflow.activation_steps_append` after activation.
98
+ If the command fails, HALT (exit code 4, `halt_reason: "write-failed"`) at phase `on-activation:run-folder`: "Cannot create the run folder `{run_dir}`: {the first stderr line}." With no folder to stage in, a headless HALT of this step passes its payload to the emitter directly, through `python3` in place of `uv run` when `uv` is what is missing:
99
+
100
+ ```bash
101
+ uv run {emitEnvelopeHelper} emit-halt --workflow skf-audit-skill --target stderr <<'SKF_AS_HALT'
102
+ {"phase": "<the phase>", "reason": "<the halt message>", "halt_reason": "<the halt_reason>"}
103
+ SKF_AS_HALT
104
+ ```
113
105
 
114
- 4. Load, read the full file, and then execute `references/init.md` to begin the workflow.
106
+ 5. Load, read the full file, and then execute `references/init.md` to begin the workflow.
@@ -8,6 +8,28 @@ skill_name: ''
8
8
  skill_path: ''
9
9
  source_path: ''
10
10
  forge_tier: ''
11
+ # Run context, written as each value is known (init §6, re-index §5,
12
+ # structural-diff §6), so later steps read it from this file.
13
+ audited_version: ''
14
+ audited_version_reason: ''
15
+ manifest_version: ''
16
+ docs_only_skill: ''
17
+ provenance_map: ''
18
+ provenance_generated_at: ''
19
+ provenance_age_days: ''
20
+ baseline_ref: ''
21
+ baseline_commit: ''
22
+ audit_ref: ''
23
+ audit_ref_source: ''
24
+ audit_commit: ''
25
+ latest_tag: ''
26
+ remote_head: ''
27
+ upstream_fetch: ''
28
+ upstream_moved: ''
29
+ upstream_ref: ''
30
+ source_tree: ''
31
+ ast_fallback_files: []
32
+ applied_transforms: []
11
33
  drift_score: ''
12
34
  nextWorkflow: ''
13
35
  previousWorkflow: 'create-skill'
@@ -17,7 +39,6 @@ previousWorkflow: 'create-skill'
17
39
 
18
40
  ## Audit Summary
19
41
 
20
- **Confidence Mode:** {confidence_mode}
21
42
  **Skill:** {skill_name}
22
43
  **Source:** {source_path}
23
44
  **Tier:** {forge_tier}
@@ -36,7 +57,9 @@ previousWorkflow: 'create-skill'
36
57
 
37
58
  ## Structural Drift
38
59
 
39
- <!-- Appended by structural-diff -->
60
+ <!-- Appended by structural-diff, or for a compose-mode stack by constituent-freshness -->
61
+ <!-- Constituent Freshness (compose-mode stacks): drifted, missing and not-compared constituents; each drifted (HIGH) or missing (MEDIUM) one is a finding -->
62
+ <!-- Provenance label differences (not drift): informational table, rendered only when label_changes[] is non-empty and excluded from Total Drift Items -->
40
63
 
41
64
  ---
42
65
 
@@ -54,13 +77,14 @@ previousWorkflow: 'create-skill'
54
77
 
55
78
  ## Documentation Drift
56
79
 
57
- <!-- Appended by step-doc-drift -->
80
+ <!-- Appended by doc-drift -->
58
81
 
59
82
  ---
60
83
 
61
84
  ## Remediation Suggestions
62
85
 
63
86
  <!-- Appended by report -->
87
+ <!-- Out-of-Scope New Public API: one row per file outside the skill's scope whose public API a package entry point exports (the snapshot's outside_scope), which update-skill's scope reconciliation reads; left out when there is none -->
64
88
 
65
89
  ---
66
90
 
@@ -1,8 +1,8 @@
1
1
  # DO NOT EDIT -- overwritten on every update.
2
2
  #
3
3
  # Workflow customization surface for skf-audit-skill.
4
- # Team overrides: _bmad/custom/skf-audit-skill.toml (under {project-root})
5
- # Personal overrides: _bmad/custom/skf-audit-skill.user.toml (under {project-root})
4
+ # Team overrides: {project-root}/_bmad/custom/skf-audit-skill.toml
5
+ # Personal overrides: {project-root}/_bmad/custom/skf-audit-skill.user.toml
6
6
 
7
7
  [workflow]
8
8
 
@@ -10,42 +10,63 @@
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 audit work.
13
+ # Steps SKILL.md On Activation step 3 runs once this file resolves: after the
14
+ # config load and the headless flag, before step 4's pre-flight (the uv and
15
+ # helper checks, the run folder) and before any stage. Overrides append. Use
16
+ # for org-wide pre-flight checks (auth, network, compliance) that must precede
17
+ # any audit work.
16
18
 
17
19
  activation_steps_prepend = []
18
20
 
19
- # Steps to run after activation but before the first stage executes.
20
- # Overrides append. Use for context loads or banner customization that
21
- # should run once activation completes successfully.
21
+ # Steps to run once activation completes (step 4's pre-flight passed), before
22
+ # references/init.md (the first stage) loads. Overrides append. Use for
23
+ # context loads or banner customization.
22
24
 
23
25
  activation_steps_append = []
24
26
 
25
27
  # Persistent facts the workflow keeps in mind for the whole run
26
- # (house style, severity-threshold policies, audit guardrails).
27
- # Overrides append.
28
+ # (house style, audit guardrails). Overrides append. Severity grades are not
29
+ # a fact: skf-severity-classify.py grades every finding by its own rule table.
28
30
  #
29
- # Each entry is either:
31
+ # Each entry is one of:
30
32
  # - a literal sentence, e.g. "Critical drift requires CODEOWNERS notification."
31
33
  # - a file reference prefixed with `file:`, e.g.
32
34
  # "file:{project-root}/docs/audit-policy.md" (globs supported; file
33
35
  # contents are loaded and treated as facts).
36
+ # - an entry prefixed with `!`, which loads nothing and drops each earlier
37
+ # entry it names.
38
+ #
39
+ # The default below loads every project-context.md under {project-root}.
40
+ # Overrides append, so they cannot delete it; to stop loading those files,
41
+ # set in {project-root}/_bmad/custom/skf-audit-skill.toml:
42
+ # persistent_facts = ["!file:{project-root}/**/project-context.md"]
34
43
 
35
44
  persistent_facts = [
36
45
  "file:{project-root}/**/project-context.md",
37
46
  ]
38
47
 
39
- # --- Optional asset overrides ---
40
- #
41
- # Lift the canonical asset paths so orgs can substitute house-style copies
42
- # without forking the skill. Empty string = use the bundled default.
48
+ # --- Optional overrides. An empty string means the default named below. ---
43
49
 
44
- drift_report_template_path = ""
45
- severity_rules_path = ""
50
+ # The template step 1 (references/init.md section 6) creates the drift report
51
+ # from. Default: assets/drift-report-template.md, a path from the skill root.
52
+ # Keep a house-style copy outside the skill folder, which every update
53
+ # overwrites, and name it as {project-root}/<path to the copy>. The copy may
54
+ # restyle the report body and must keep:
55
+ # - every frontmatter key of the bundled template: the steps write the run
56
+ # context, stepsCompleted, drift_score and nextWorkflow there, and step 6
57
+ # builds the Provenance table from them;
58
+ # - the `## Audit Summary` section with its severity count table, which
59
+ # step 6 fills in. The stages write every drift section themselves.
46
60
 
47
- # Optional post-audit hook. When non-empty, invoked with
48
- # `--result-path=<path>` after the drift report and result JSON are finalized.
49
- # Failures are logged to workflow_warnings[] but never fail the workflow.
61
+ drift_report_template_path = "assets/drift-report-template.md"
62
+
63
+ # Optional post-audit hook: a shell command run from {project-root}, not an
64
+ # agent instruction. Step 6 (references/report.md) runs it on a finished
65
+ # audit, after the emitter wrote the result files, as:
66
+ # <on_complete> --result-path=<{forge_version}/audit-skill-result-<YYYYMMDD-HHmmss>.json>
67
+ # It never runs on a halt, nor when the result file could not be written. A
68
+ # failure is shown to the user and never fails the audit.
69
+ #
70
+ # Empty string = no-op (default).
50
71
 
51
72
  on_complete = ""