bmad-module-skill-forge 2.1.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (435) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/README.md +51 -49
  3. package/docs/404.md +10 -8
  4. package/docs/_data/pinned.yaml +22 -13
  5. package/docs/_internal/STABILITY.md +58 -35
  6. package/docs/agents.md +39 -53
  7. package/docs/architecture.md +65 -51
  8. package/docs/bmad-synergy.md +53 -51
  9. package/docs/campaign.md +127 -75
  10. package/docs/concepts.md +34 -28
  11. package/docs/examples.md +70 -68
  12. package/docs/forge-auto.md +34 -31
  13. package/docs/getting-started.md +118 -57
  14. package/docs/how-it-works.md +25 -21
  15. package/docs/index.md +15 -15
  16. package/docs/skill-model.md +70 -59
  17. package/docs/troubleshooting.md +135 -18
  18. package/docs/verifying-a-skill.md +83 -57
  19. package/docs/why-skf.md +24 -22
  20. package/docs/workflows.md +274 -110
  21. package/package.json +18 -10
  22. package/src/forger/preferences.yaml +8 -1
  23. package/src/knowledge/agentskills-spec.md +2 -0
  24. package/src/knowledge/ccc-bridge.md +40 -24
  25. package/src/knowledge/confidence-tiers.md +9 -5
  26. package/src/knowledge/overview.md +3 -3
  27. package/src/knowledge/progressive-capability.md +8 -8
  28. package/src/knowledge/provenance-tracking.md +9 -5
  29. package/src/knowledge/qmd-registry.md +2 -2
  30. package/src/knowledge/skf-knowledge-index.csv +2 -2
  31. package/src/knowledge/skill-lifecycle.md +18 -11
  32. package/src/knowledge/split-body-strategy.md +0 -3
  33. package/src/knowledge/tool-resolution.md +4 -2
  34. package/src/knowledge/version-paths.md +101 -15
  35. package/src/module-help.csv +3 -3
  36. package/src/module.yaml +10 -0
  37. package/src/shared/data/ast-grep-recipes.yaml +608 -0
  38. package/src/shared/data/ide-context-files.json +30 -0
  39. package/src/shared/health-check.md +32 -12
  40. package/src/shared/references/description-guard-protocol.md +14 -9
  41. package/src/shared/references/feasibility-report-schema.md +19 -13
  42. package/src/shared/references/headless-gate-convention.md +55 -3
  43. package/src/shared/references/output-contract-schema.md +19 -8
  44. package/src/shared/references/pipeline-contracts.md +94 -29
  45. package/src/shared/references/tessl-review.md +77 -0
  46. package/src/shared/scripts/schemas/skf-analyze-result-envelope.v1.json +194 -0
  47. package/src/shared/scripts/schemas/skf-audit-result-envelope.v1.json +192 -0
  48. package/src/shared/scripts/schemas/skf-brief-result-envelope.v1.json +32 -4
  49. package/src/shared/scripts/schemas/skf-campaign-result-envelope.v1.json +174 -0
  50. package/src/shared/scripts/schemas/skf-create-skill-result-envelope.v1.json +284 -0
  51. package/src/shared/scripts/schemas/skf-drop-skill-result-envelope.v1.json +164 -0
  52. package/src/shared/scripts/schemas/skf-export-result-envelope.v1.json +160 -0
  53. package/src/shared/scripts/schemas/skf-quick-skill-result-envelope.v1.json +261 -0
  54. package/src/shared/scripts/schemas/skf-refine-architecture-result-envelope.v1.json +192 -0
  55. package/src/shared/scripts/schemas/skf-rename-skill-result-envelope.v1.json +179 -0
  56. package/src/shared/scripts/schemas/skf-setup-result-envelope.v1.json +27 -11
  57. package/src/shared/scripts/schemas/skf-stack-result-envelope.v1.json +176 -0
  58. package/src/shared/scripts/schemas/skf-test-result-envelope.v1.json +173 -0
  59. package/src/shared/scripts/schemas/skf-update-result-envelope.v1.json +19 -5
  60. package/src/shared/scripts/schemas/skf-verify-stack-result-envelope.v1.json +180 -0
  61. package/src/shared/scripts/schemas/skill-brief.v1.json +34 -0
  62. package/src/shared/scripts/schemas/workspace-detection.v1.json +1 -1
  63. package/src/shared/scripts/skf-atomic-write.py +30 -14
  64. package/src/shared/scripts/skf-build-change-manifest.py +2203 -24
  65. package/src/shared/scripts/skf-ccc-git-hygiene.py +532 -0
  66. package/src/shared/scripts/skf-check-unit-records.py +184 -0
  67. package/src/shared/scripts/skf-check-workspace-drift.py +538 -9
  68. package/src/shared/scripts/skf-classify-changed-files.py +694 -0
  69. package/src/shared/scripts/skf-comention-pairs.py +1333 -123
  70. package/src/shared/scripts/skf-compare-file-hashes.py +1 -1
  71. package/src/shared/scripts/skf-count-imports.py +1867 -0
  72. package/src/shared/scripts/skf-count-tokens.py +1 -1
  73. package/src/shared/scripts/skf-derive-assembly-shape.py +3 -2
  74. package/src/shared/scripts/skf-description-guard.py +117 -9
  75. package/src/shared/scripts/skf-detect-docs.py +892 -4
  76. package/src/shared/scripts/skf-detect-language.py +486 -107
  77. package/src/shared/scripts/skf-detect-registry.py +887 -0
  78. package/src/shared/scripts/skf-detect-scripts-assets.py +1 -1
  79. package/src/shared/scripts/skf-detect-tools.py +215 -27
  80. package/src/shared/scripts/skf-detect-workspaces.py +506 -30
  81. package/src/shared/scripts/skf-disqualify-candidates.py +821 -182
  82. package/src/shared/scripts/skf-emit-brief-result-envelope.py +69 -191
  83. package/src/shared/scripts/skf-emit-result-envelope.py +1604 -106
  84. package/src/shared/scripts/skf-enumerate-stack-skills.py +986 -117
  85. package/src/shared/scripts/skf-extract-public-api.py +4084 -85
  86. package/src/shared/scripts/skf-extraction-inventory.py +746 -0
  87. package/src/shared/scripts/skf-extraction-snapshot.py +539 -0
  88. package/src/shared/scripts/skf-fetch-temporal.py +674 -0
  89. package/src/shared/scripts/skf-find-cycles.py +97 -29
  90. package/src/shared/scripts/skf-find-test-report.py +476 -0
  91. package/src/shared/scripts/skf-forge-tier-rw.py +444 -203
  92. package/src/shared/scripts/skf-github-fetch.py +365 -0
  93. package/src/shared/scripts/skf-github-probe.py +661 -0
  94. package/src/shared/scripts/skf-hash-content.py +166 -12
  95. package/src/shared/scripts/skf-language-corpora.py +1 -1
  96. package/src/shared/scripts/skf-load-provenance.py +159 -27
  97. package/src/shared/scripts/skf-manifest-ops.py +1 -1
  98. package/src/shared/scripts/skf-merge-ccc-exclusions.py +2307 -223
  99. package/src/shared/scripts/skf-merge-doc-urls.py +1 -1
  100. package/src/shared/scripts/skf-names-present.py +221 -0
  101. package/src/shared/scripts/skf-pair-intersect.py +119 -28
  102. package/src/shared/scripts/skf-parse-gaps.py +1384 -0
  103. package/src/shared/scripts/skf-preapply.py +1 -1
  104. package/src/shared/scripts/skf-preflight.py +161 -27
  105. package/src/shared/scripts/skf-promote-staged.py +430 -0
  106. package/src/shared/scripts/skf-provenance-gap-dispatch.py +39 -7
  107. package/src/shared/scripts/skf-qmd-classify-collections.py +229 -45
  108. package/src/shared/scripts/skf-quick-batch.py +774 -0
  109. package/src/shared/scripts/skf-rebuild-managed-sections.py +972 -88
  110. package/src/shared/scripts/skf-recommend-scope-type.py +323 -156
  111. package/src/shared/scripts/skf-render-metadata-stats.py +156 -12
  112. package/src/shared/scripts/skf-render-quick-metadata.py +132 -28
  113. package/src/shared/scripts/skf-render-stack-metadata.py +976 -0
  114. package/src/shared/scripts/skf-resolve-authoritative-files.py +128 -13
  115. package/src/shared/scripts/skf-resolve-package.py +523 -106
  116. package/src/shared/scripts/skf-rewrite-skill-name.py +433 -47
  117. package/src/shared/scripts/skf-run-lock.py +577 -0
  118. package/src/shared/scripts/skf-scan-manifests.py +998 -57
  119. package/src/shared/scripts/skf-scan-skill-md-structure.py +1341 -37
  120. package/src/shared/scripts/skf-severity-classify.py +712 -108
  121. package/src/shared/scripts/skf-shape-detect.py +298 -204
  122. package/src/shared/scripts/skf-shard-body.py +9 -8
  123. package/src/shared/scripts/skf-skill-inventory.py +2412 -89
  124. package/src/shared/scripts/skf-skills-module.py +472 -0
  125. package/src/shared/scripts/skf-source-tree.py +1796 -0
  126. package/src/shared/scripts/skf-structural-diff.py +670 -119
  127. package/src/shared/scripts/skf-tessl-review.py +706 -0
  128. package/src/shared/scripts/skf-update-active-symlink.py +5 -5
  129. package/src/shared/scripts/skf-update-run-state.py +624 -0
  130. package/src/shared/scripts/skf-validate-brief-inputs.py +92 -29
  131. package/src/shared/scripts/skf-validate-brief-schema.py +4 -1
  132. package/src/shared/scripts/skf-validate-feasibility-report.py +577 -66
  133. package/src/shared/scripts/skf-validate-frontmatter.py +103 -26
  134. package/src/shared/scripts/skf-validate-output.py +712 -64
  135. package/src/shared/scripts/skf-validate-pins.py +1 -1
  136. package/src/shared/scripts/skf-verify-no-trace.py +116 -10
  137. package/src/shared/scripts/skf-verify-provenance-completeness.py +2919 -54
  138. package/src/shared/scripts/skf-write-skill-brief.py +367 -19
  139. package/src/shared/tool-requirements.yaml +201 -0
  140. package/src/skf-analyze-source/SKILL.md +41 -36
  141. package/src/skf-analyze-source/assets/skill-brief-schema.md +7 -8
  142. package/src/skf-analyze-source/customize.toml +36 -24
  143. package/src/skf-analyze-source/references/auto-docs-only.md +58 -20
  144. package/src/skf-analyze-source/references/continue.md +2 -13
  145. package/src/skf-analyze-source/references/discover-additional-source.md +147 -0
  146. package/src/skf-analyze-source/references/generate-briefs.md +121 -55
  147. package/src/skf-analyze-source/references/headless-contract.md +42 -15
  148. package/src/skf-analyze-source/references/identify-units.md +96 -110
  149. package/src/skf-analyze-source/references/init.md +73 -71
  150. package/src/skf-analyze-source/references/map-and-detect.md +123 -105
  151. package/src/skf-analyze-source/references/map-unit-exports.md +68 -0
  152. package/src/skf-analyze-source/references/recommend.md +51 -70
  153. package/src/skf-analyze-source/references/scan-project.md +60 -84
  154. package/src/skf-analyze-source/references/scan-root.md +39 -0
  155. package/src/skf-analyze-source/references/step-auto-scope-coexistence.md +47 -0
  156. package/src/skf-analyze-source/references/step-auto-scope-corpora.md +53 -0
  157. package/src/skf-analyze-source/references/step-auto-scope-split.md +91 -0
  158. package/src/skf-analyze-source/references/step-auto-scope.md +208 -293
  159. package/src/skf-analyze-source/references/step-shape-detect.md +14 -12
  160. package/src/skf-analyze-source/references/unit-detection-heuristics.md +37 -42
  161. package/src/skf-audit-skill/SKILL.md +43 -51
  162. package/src/skf-audit-skill/assets/drift-report-template.md +27 -3
  163. package/src/skf-audit-skill/customize.toml +41 -20
  164. package/src/skf-audit-skill/references/constituent-freshness.md +91 -0
  165. package/src/skf-audit-skill/references/doc-drift.md +141 -0
  166. package/src/skf-audit-skill/references/headless-contract.md +29 -0
  167. package/src/skf-audit-skill/references/init.md +148 -210
  168. package/src/skf-audit-skill/references/re-index.md +96 -108
  169. package/src/skf-audit-skill/references/report.md +96 -33
  170. package/src/skf-audit-skill/references/semantic-diff.md +27 -18
  171. package/src/skf-audit-skill/references/severity-classify.md +79 -65
  172. package/src/skf-audit-skill/references/severity-rules.md +15 -6
  173. package/src/skf-audit-skill/references/structural-diff.md +75 -90
  174. package/src/skf-audit-skill/references/upstream-checkout.md +77 -0
  175. package/src/skf-audit-skill/scripts/render-drift-tables.py +685 -0
  176. package/src/skf-brief-skill/SKILL.md +36 -25
  177. package/src/skf-brief-skill/assets/description-voice-examples.md +1 -1
  178. package/src/skf-brief-skill/assets/scope-templates.md +17 -24
  179. package/src/skf-brief-skill/assets/skill-brief-schema.md +29 -15
  180. package/src/skf-brief-skill/customize.toml +48 -20
  181. package/src/skf-brief-skill/references/analyze-target.md +142 -125
  182. package/src/skf-brief-skill/references/confirm-brief.md +10 -8
  183. package/src/skf-brief-skill/references/draft-checkpoint.md +36 -17
  184. package/src/skf-brief-skill/references/gather-intent-ratify.md +68 -0
  185. package/src/skf-brief-skill/references/gather-intent.md +87 -182
  186. package/src/skf-brief-skill/references/headless-args.md +84 -16
  187. package/src/skf-brief-skill/references/health-check.md +1 -1
  188. package/src/skf-brief-skill/references/invocation-contract.md +18 -13
  189. package/src/skf-brief-skill/references/portfolio-similarity-check.md +1 -1
  190. package/src/skf-brief-skill/references/qmd-collection-registration.md +7 -10
  191. package/src/skf-brief-skill/references/scope-definition.md +123 -47
  192. package/src/skf-brief-skill/references/step-auto-brief.md +24 -80
  193. package/src/skf-brief-skill/references/step-auto-validate.md +20 -121
  194. package/src/skf-brief-skill/references/version-resolution.md +3 -2
  195. package/src/skf-brief-skill/references/write-brief.md +66 -57
  196. package/src/skf-campaign/SKILL.md +31 -34
  197. package/src/skf-campaign/assets/campaign-state-schema.json +25 -4
  198. package/src/skf-campaign/customize.toml +47 -16
  199. package/src/skf-campaign/references/campaign-contracts.md +39 -29
  200. package/src/skf-campaign/references/campaign-directive-spec.md +4 -2
  201. package/src/skf-campaign/references/health-check.md +7 -16
  202. package/src/skf-campaign/references/step-01-setup.md +46 -84
  203. package/src/skf-campaign/references/step-02-strategy.md +31 -30
  204. package/src/skf-campaign/references/step-03-pins.md +26 -18
  205. package/src/skf-campaign/references/step-04-provenance.md +24 -23
  206. package/src/skf-campaign/references/step-05-skill-loop.md +67 -48
  207. package/src/skf-campaign/references/step-06-batch.md +41 -34
  208. package/src/skf-campaign/references/step-07-capstone.md +40 -25
  209. package/src/skf-campaign/references/step-08-verify.md +28 -29
  210. package/src/skf-campaign/references/step-09-refine.md +29 -30
  211. package/src/skf-campaign/references/step-10-export.md +48 -36
  212. package/src/skf-campaign/references/step-11-maintenance.md +31 -34
  213. package/src/skf-campaign/references/step-resume.md +37 -68
  214. package/src/skf-campaign/scripts/campaign-deps.py +57 -18
  215. package/src/skf-campaign/scripts/campaign-parse-manifest.py +361 -54
  216. package/src/skf-campaign/scripts/campaign-provenance.py +96 -53
  217. package/src/skf-campaign/scripts/campaign-quality-gate.py +592 -0
  218. package/src/skf-campaign/scripts/campaign-render-batch.py +257 -49
  219. package/src/skf-campaign/scripts/campaign-render-kickoff.py +343 -50
  220. package/src/skf-campaign/scripts/campaign-report.py +204 -37
  221. package/src/skf-campaign/scripts/campaign-state.py +1128 -0
  222. package/src/skf-campaign/scripts/campaign-status.py +10 -74
  223. package/src/skf-campaign/scripts/campaign-validate-pins.py +30 -3
  224. package/src/skf-campaign/scripts/campaign-validate-state.py +34 -4
  225. package/src/skf-campaign/templates/campaign-brief-template.yaml +4 -5
  226. package/src/skf-campaign/templates/campaign-report-template.md +5 -1
  227. package/src/skf-campaign/templates/kickoff-template.md +0 -14
  228. package/src/skf-create-skill/SKILL.md +27 -20
  229. package/src/skf-create-skill/assets/compile-assembly-rules.md +6 -5
  230. package/src/skf-create-skill/assets/skill-sections.md +17 -6
  231. package/src/skf-create-skill/customize.toml +20 -8
  232. package/src/skf-create-skill/references/authoritative-files-protocol.md +41 -42
  233. package/src/skf-create-skill/references/batch-mode.md +81 -0
  234. package/src/skf-create-skill/references/ccc-index-check.md +27 -0
  235. package/src/skf-create-skill/references/compile.md +107 -29
  236. package/src/skf-create-skill/references/component-extraction.md +113 -91
  237. package/src/skf-create-skill/references/enrich.md +41 -23
  238. package/src/skf-create-skill/references/entry-points-by-hand.md +20 -0
  239. package/src/skf-create-skill/references/extract.md +200 -161
  240. package/src/skf-create-skill/references/extraction-patterns-by-hand.md +141 -0
  241. package/src/skf-create-skill/references/extraction-patterns-tracing.md +2 -2
  242. package/src/skf-create-skill/references/extraction-patterns.md +584 -196
  243. package/src/skf-create-skill/references/generate-artifacts.md +145 -93
  244. package/src/skf-create-skill/references/health-check.md +1 -1
  245. package/src/skf-create-skill/references/load-brief.md +53 -36
  246. package/src/skf-create-skill/references/relabel-rule.md +12 -0
  247. package/src/skf-create-skill/references/report.md +28 -59
  248. package/src/skf-create-skill/references/source-resolution-protocols.md +49 -155
  249. package/src/skf-create-skill/references/step-auto-shard.md +20 -93
  250. package/src/skf-create-skill/references/step-doc-rot.md +44 -60
  251. package/src/skf-create-skill/references/step-doc-sources.md +55 -18
  252. package/src/skf-create-skill/references/sub/ccc-discover.md +18 -7
  253. package/src/skf-create-skill/references/sub/fetch-docs.md +106 -57
  254. package/src/skf-create-skill/references/sub/fetch-temporal.md +53 -166
  255. package/src/skf-create-skill/references/tier-degradation-rules.md +18 -9
  256. package/src/skf-create-skill/references/validate.md +173 -99
  257. package/src/skf-create-skill/scripts/scan-doc-rot.py +232 -99
  258. package/src/skf-create-stack-skill/SKILL.md +29 -56
  259. package/src/skf-create-stack-skill/assets/metadata-contract.md +51 -0
  260. package/src/skf-create-stack-skill/assets/provenance-map-schema.md +15 -15
  261. package/src/skf-create-stack-skill/assets/stack-skill-template.md +23 -57
  262. package/src/skf-create-stack-skill/customize.toml +23 -12
  263. package/src/skf-create-stack-skill/references/compile-stack.md +57 -66
  264. package/src/skf-create-stack-skill/references/compose-mode-rules.md +24 -44
  265. package/src/skf-create-stack-skill/references/detect-integrations.md +92 -95
  266. package/src/skf-create-stack-skill/references/detect-manifests.md +46 -71
  267. package/src/skf-create-stack-skill/references/generate-output.md +138 -128
  268. package/src/skf-create-stack-skill/references/init.md +90 -32
  269. package/src/skf-create-stack-skill/references/integration-patterns.md +1 -17
  270. package/src/skf-create-stack-skill/references/invocation-contract.md +34 -0
  271. package/src/skf-create-stack-skill/references/manifest-patterns.md +32 -20
  272. package/src/skf-create-stack-skill/references/parallel-extract.md +112 -38
  273. package/src/skf-create-stack-skill/references/rank-and-confirm.md +57 -75
  274. package/src/skf-create-stack-skill/references/report.md +39 -33
  275. package/src/skf-create-stack-skill/references/validate.md +20 -39
  276. package/src/skf-drop-skill/SKILL.md +28 -51
  277. package/src/skf-drop-skill/customize.toml +44 -30
  278. package/src/skf-drop-skill/references/execute.md +79 -146
  279. package/src/skf-drop-skill/references/invocation-contract.md +64 -0
  280. package/src/skf-drop-skill/references/report.md +46 -30
  281. package/src/skf-drop-skill/references/select.md +118 -124
  282. package/src/skf-drop-skill/scripts/dir-sizes.py +54 -26
  283. package/src/skf-drop-skill/scripts/drop-roster.py +322 -0
  284. package/src/skf-export-skill/SKILL.md +40 -62
  285. package/src/skf-export-skill/assets/managed-section-format.md +14 -50
  286. package/src/skf-export-skill/assets/snippet-format.md +3 -1
  287. package/src/skf-export-skill/customize.toml +42 -13
  288. package/src/skf-export-skill/references/generate-snippet.md +54 -46
  289. package/src/skf-export-skill/references/health-check.md +2 -0
  290. package/src/skf-export-skill/references/invocation-contract.md +15 -0
  291. package/src/skf-export-skill/references/load-skill.md +88 -62
  292. package/src/skf-export-skill/references/manifest-rebuild.md +9 -10
  293. package/src/skf-export-skill/references/multi-skill-mode.md +4 -4
  294. package/src/skf-export-skill/references/orphan-context-detection.md +13 -5
  295. package/src/skf-export-skill/references/orphan-row-detection.md +31 -22
  296. package/src/skf-export-skill/references/package.md +15 -73
  297. package/src/skf-export-skill/references/preflight-snippet-root-probe.md +51 -70
  298. package/src/skf-export-skill/references/result-envelope.md +31 -16
  299. package/src/skf-export-skill/references/summary.md +41 -17
  300. package/src/skf-export-skill/references/token-report.md +4 -12
  301. package/src/skf-export-skill/references/update-context.md +118 -237
  302. package/src/skf-forger/SKILL.md +61 -37
  303. package/src/skf-forger/bmad-skill-manifest.yaml +4 -1
  304. package/src/skf-forger/customize.toml +43 -0
  305. package/src/skf-forger/references/pipeline-mode.md +73 -18
  306. package/src/skf-forger/scripts/forge-status.py +299 -0
  307. package/src/skf-forger/scripts/parse-pipeline.py +322 -54
  308. package/src/skf-forger/scripts/pipeline-gate.py +428 -0
  309. package/src/skf-forger/scripts/pipeline-journal.py +1052 -0
  310. package/src/skf-quick-skill/SKILL.md +54 -53
  311. package/src/skf-quick-skill/assets/skill-template.md +4 -2
  312. package/src/skf-quick-skill/customize.toml +51 -20
  313. package/src/skf-quick-skill/references/batch-mode.md +74 -21
  314. package/src/skf-quick-skill/references/compile.md +30 -31
  315. package/src/skf-quick-skill/references/ecosystem-check.md +7 -57
  316. package/src/skf-quick-skill/references/finalize.md +69 -18
  317. package/src/skf-quick-skill/references/halt-contract.md +41 -29
  318. package/src/skf-quick-skill/references/health-check.md +5 -3
  319. package/src/skf-quick-skill/references/quick-extract.md +114 -45
  320. package/src/skf-quick-skill/references/registry-resolution.md +9 -64
  321. package/src/skf-quick-skill/references/resolve-target.md +116 -66
  322. package/src/skf-quick-skill/references/write-and-validate.md +79 -40
  323. package/src/skf-refine-architecture/SKILL.md +43 -53
  324. package/src/skf-refine-architecture/customize.toml +49 -20
  325. package/src/skf-refine-architecture/references/compile.md +97 -54
  326. package/src/skf-refine-architecture/references/exit-codes.md +30 -0
  327. package/src/skf-refine-architecture/references/finding-storage.md +21 -0
  328. package/src/skf-refine-architecture/references/gap-analysis.md +101 -38
  329. package/src/skf-refine-architecture/references/improvements.md +14 -20
  330. package/src/skf-refine-architecture/references/init.md +98 -57
  331. package/src/skf-refine-architecture/references/issue-detection.md +32 -39
  332. package/src/skf-refine-architecture/references/refinement-rules.md +37 -48
  333. package/src/skf-refine-architecture/references/report.md +65 -54
  334. package/src/skf-refine-architecture/scripts/skf-check-preservation.py +1619 -0
  335. package/src/skf-rename-skill/SKILL.md +19 -54
  336. package/src/skf-rename-skill/customize.toml +32 -26
  337. package/src/skf-rename-skill/references/execute.md +230 -184
  338. package/src/skf-rename-skill/references/exit-codes.md +7 -7
  339. package/src/skf-rename-skill/references/health-check.md +1 -7
  340. package/src/skf-rename-skill/references/invocation-contract.md +25 -0
  341. package/src/skf-rename-skill/references/report.md +63 -52
  342. package/src/skf-rename-skill/references/select.md +197 -115
  343. package/src/skf-rename-skill/scripts/skf-validate-rename-name.py +161 -21
  344. package/src/skf-setup/SKILL.md +26 -26
  345. package/src/skf-setup/customize.toml +14 -10
  346. package/src/skf-setup/references/auto-index.md +50 -63
  347. package/src/skf-setup/references/ccc-index.md +29 -89
  348. package/src/skf-setup/references/detect-and-tier.md +58 -66
  349. package/src/skf-setup/references/health-check.md +2 -0
  350. package/src/skf-setup/references/invocation-contract.md +14 -0
  351. package/src/skf-setup/references/report.md +43 -166
  352. package/src/skf-setup/references/tier-rules.md +5 -5
  353. package/src/skf-setup/references/write-config.md +34 -57
  354. package/src/skf-test-skill/SKILL.md +17 -57
  355. package/src/skf-test-skill/assets/output-section-formats.md +33 -34
  356. package/src/skf-test-skill/customize.toml +27 -13
  357. package/src/skf-test-skill/references/coherence-check.md +134 -62
  358. package/src/skf-test-skill/references/coverage-check-tiers.md +35 -0
  359. package/src/skf-test-skill/references/coverage-check.md +217 -254
  360. package/src/skf-test-skill/references/detect-mode.md +5 -5
  361. package/src/skf-test-skill/references/external-validators.md +94 -82
  362. package/src/skf-test-skill/references/health-check.md +6 -7
  363. package/src/skf-test-skill/references/init.md +163 -88
  364. package/src/skf-test-skill/references/invocation-contract.md +66 -0
  365. package/src/skf-test-skill/references/migration-section-rules.md +5 -2
  366. package/src/skf-test-skill/references/report.md +162 -142
  367. package/src/skf-test-skill/references/score.md +80 -107
  368. package/src/skf-test-skill/references/scoring-rules.md +41 -155
  369. package/src/skf-test-skill/references/source-access-protocol.md +19 -92
  370. package/src/skf-test-skill/references/step-hard-gate.md +51 -33
  371. package/src/skf-test-skill/scripts/aggregate-coherence.py +218 -30
  372. package/src/skf-test-skill/scripts/build-result-context.py +287 -0
  373. package/src/skf-test-skill/scripts/check-metadata-coherence.py +37 -4
  374. package/src/skf-test-skill/scripts/combine-external-scores.py +23 -6
  375. package/src/skf-test-skill/scripts/compute-score.py +223 -45
  376. package/src/skf-test-skill/scripts/gap-ledger.py +1381 -0
  377. package/src/skf-test-skill/scripts/hard-gate.py +203 -0
  378. package/src/skf-test-skill/scripts/load-coverage-inputs.py +760 -0
  379. package/src/skf-test-skill/scripts/locate-export-segments.py +835 -0
  380. package/src/skf-test-skill/scripts/reconcile-coverage.py +273 -79
  381. package/src/skf-test-skill/scripts/score-signatures.py +459 -0
  382. package/src/skf-test-skill/scripts/stage-helper-payload.py +148 -0
  383. package/src/skf-test-skill/scripts/validate-inventory.py +311 -16
  384. package/src/skf-test-skill/scripts/verify-declared-numerator.py +127 -52
  385. package/src/skf-test-skill/templates/test-report-template.md +21 -15
  386. package/src/skf-update-skill/SKILL.md +38 -25
  387. package/src/skf-update-skill/customize.toml +27 -12
  388. package/src/skf-update-skill/references/detect-changes.md +233 -222
  389. package/src/skf-update-skill/references/gap-driven.md +336 -0
  390. package/src/skf-update-skill/references/health-check.md +31 -5
  391. package/src/skf-update-skill/references/init.md +250 -84
  392. package/src/skf-update-skill/references/invocation-contract.md +12 -0
  393. package/src/skf-update-skill/references/manual-section-rules.md +6 -23
  394. package/src/skf-update-skill/references/merge.md +180 -47
  395. package/src/skf-update-skill/references/re-extract.md +53 -262
  396. package/src/skf-update-skill/references/report.md +100 -35
  397. package/src/skf-update-skill/references/write.md +331 -149
  398. package/src/skf-update-skill/scripts/skf-new-file-diff.py +29 -7
  399. package/src/skf-verify-stack/SKILL.md +23 -42
  400. package/src/skf-verify-stack/assets/feasibility-report-template.md +11 -5
  401. package/src/skf-verify-stack/customize.toml +55 -22
  402. package/src/skf-verify-stack/references/coverage-patterns.md +17 -8
  403. package/src/skf-verify-stack/references/coverage.md +67 -64
  404. package/src/skf-verify-stack/references/exit-codes.md +21 -8
  405. package/src/skf-verify-stack/references/init.md +107 -62
  406. package/src/skf-verify-stack/references/integration-verification-rules.md +12 -13
  407. package/src/skf-verify-stack/references/integrations.md +106 -65
  408. package/src/skf-verify-stack/references/report.md +59 -42
  409. package/src/skf-verify-stack/references/requirements.md +32 -9
  410. package/src/skf-verify-stack/references/synthesize.md +53 -39
  411. package/src/skf-verify-stack/scripts/skf-coverage-tally.py +398 -52
  412. package/src/skf-verify-stack/scripts/skf-previous-report.py +330 -0
  413. package/src/skf-verify-stack/scripts/skf-report-delta.py +453 -49
  414. package/src/skf-verify-stack/scripts/skf-verdict-rollup.py +240 -27
  415. package/tools/cli/commands/install.js +11 -4
  416. package/tools/cli/commands/status.js +15 -3
  417. package/tools/cli/commands/update.js +11 -4
  418. package/tools/cli/lib/tool-check.js +320 -0
  419. package/tools/cli/lib/version-check.js +22 -9
  420. package/tools/cli/skf-cli.js +4 -1
  421. package/.gitattributes +0 -16
  422. package/.nvmrc +0 -1
  423. package/docs/_internal/RELEASING.md +0 -645
  424. package/release-audits/v1.0.0-launch-audit.md +0 -728
  425. package/src/skf-audit-skill/references/step-doc-drift.md +0 -177
  426. package/src/skf-brief-skill/references/headless-source-authority-detection.md +0 -26
  427. package/src/skf-campaign/manifest.yaml +0 -15
  428. package/src/skf-create-skill/assets/tessl-dismissal-rules.md +0 -106
  429. package/src/skf-create-skill/references/ecosystem-check.md +0 -74
  430. package/src/skf-drop-skill/references/headless-contract.md +0 -18
  431. package/src/skf-update-skill/references/merge-conflict-rules.md +0 -15
  432. package/src/skf-update-skill/references/remote-source-resolution.md +0 -98
  433. package/src/skf-update-skill/references/validate.md +0 -124
  434. package/tools/validate-docs-drift.js +0 -233
  435. package/tools/validate-docs-links.js +0 -665
@@ -1,25 +1,26 @@
1
1
  ---
2
2
  name: skf-refine-architecture
3
- description: Improve architecture doc using verified skill data and VS feasibility findings. Use when the user requests to "refine skill architecture" or "improve architecture doc."
3
+ description: Refines an architecture document against generated skills and a Verify Stack report. Use when the user requests to "refine the architecture against generated skills" or "refine an architecture doc with a VS report."
4
4
  ---
5
5
 
6
6
  # Refine Architecture
7
7
 
8
8
  ## Overview
9
9
 
10
- Takes an original architecture document + generated skills + optional VS feasibility report, and produces a refined architecture with gaps filled, issues flagged, and improvements suggested — all backed by specific API evidence from the generated skills. This workflow enhances the original architecture — it never deletes original content, only adds annotations, subsections, and suggestions.
10
+ Produces a refined architecture document: gaps filled, issues flagged and improvements suggested from the generated skills and an optional VS feasibility report. It never deletes original content, only adds annotations, subsections and suggestions between `<!-- RA:BEGIN ... -->` and `<!-- RA:END -->` marker lines; run again on a refined document, it sets its earlier annotations aside and writes one current set.
11
11
 
12
12
  ## Conventions
13
13
 
14
14
  - Bare paths (e.g. `references/<name>.md`) resolve from the skill root.
15
- - `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.
16
17
  - `{skill-root}` resolves to this skill's installed directory (where `customize.toml` lives, if present).
17
18
  - `{project-root}`-prefixed paths resolve from the project working directory.
18
19
  - `{skill-name}` resolves to the skill directory's basename.
19
20
 
20
21
  ## Role
21
22
 
22
- You are an architecture refinement analyst operating in Ferris Architect mode. You bring expertise in API surface analysis, integration gap detection, and evidence-backed architecture improvement, while the user brings their architecture vision and generated skills. Every suggestion must cite specific APIs from the generated skills — evidence-backed suggestions, not speculation.
23
+ You are an architecture refinement analyst in Ferris Architect mode; the user brings the architecture vision and the generated skills.
23
24
 
24
25
  ## Workflow Rules
25
26
 
@@ -27,17 +28,18 @@ These rules apply to every step in this workflow:
27
28
 
28
29
  - Never speculate — every gap, issue, or improvement must cite specific APIs, types, or function signatures from the generated skills
29
30
  - Only load one step file at a time — never preload future steps
30
- - If any instruction references a subprocess or tool you lack, achieve the outcome in your main context thread
31
31
  - Always communicate in `{communication_language}`
32
32
  - At any interactive prompt, the inputs `cancel`, `exit`, `[X]`, `q`, or `:q` exit cleanly with exit code 6 (`halt_reason: "user-cancelled"`)
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; a gate that picks its default records that decision in the run sink the moment it decides
34
+ - Every HARD HALT names its exit code, `halt_reason` and phase, and in headless mode prints the envelope the Result Contract below describes
35
+ - Run state lives in `{run_dir}`, not in context; step 6 deletes it when the run finishes, a HALT keeps it
34
36
 
35
37
  ## Stages
36
38
 
37
39
  | # | Step | File | Auto-proceed |
38
40
  |---|------|------|--------------|
39
- | 1 | Initialize & Load Inputs | references/init.md | No (confirm) |
40
- | 2 | Gap Analysis | references/gap-analysis.md | Yes |
41
+ | 1 | Initialize & Load Inputs | references/init.md | No (input gate) |
42
+ | 2 | Gap Analysis | references/gap-analysis.md | Conditional (confirm a derived scope) |
41
43
  | 3 | Issue Detection | references/issue-detection.md | Yes |
42
44
  | 4 | Improvements | references/improvements.md | Yes |
43
45
  | 5 | Compile Refined Architecture | references/compile.md | No (review) |
@@ -49,36 +51,14 @@ These rules apply to every step in this workflow:
49
51
  | Aspect | Detail |
50
52
  |--------|--------|
51
53
  | **Inputs** | architecture_doc_path [required], vs_report_path [optional] |
52
- | **Flags** | `--headless` / `-H` (auto-resolve all gates); `--architecture-doc <path>` (skip step 1 prompt for the required input); `--vs-report-path <path>` (skip step 1 prompt for the optional VS report); `--scope-skills <names>` (comma-separated in-scope skill names; overrides scope derivation in gap analysis) |
53
- | **Gates** | step 1: Input Gate [use args] | step 5: Review Gate [C] continue / [X] cancel | step 6: Exit menu [R] review / [X] exit |
54
- | **Outputs** | `refined-architecture-{arch_project_name}.md` at `{outputFolderPath}` (`{arch_project_name}` = the architecture doc's frontmatter `project_name`, else config `project_name` — resolved in init.md), plus `refine-architecture-result-{timestamp}.json` and `refine-architecture-result-latest.json` |
55
- | **Headless** | All gates auto-resolve with default action when `{headless_mode}` is true. Per-flag args (`--architecture-doc`, `--vs-report-path`) 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) |
65
- | 2 | input-missing / input-invalid | step 1 §1 (headless missing `architecture-doc` arg, or invalid path) → `input-missing`; non-existent file → `input-invalid` |
66
- | 3 | resolution-failure | On-Activation §5 (`output_folder` or `forge_data_folder` unconfigured) |
67
- | 4 | write-failure | On-Activation §5 pre-flight write probe; step 1 §3c (RA state file write failed); step 5 §6 (refined-architecture write failed); step 6 §3 (result-contract write failed) |
68
- | 5 | state-conflict | step 1 §3 (no skills found — refinement requires ≥1 skill) |
69
- | 6 | user-cancelled | step 1 §1 prompt cancelled; any prompt that accepted `cancel`/`exit`/`:q`; step 5 review gate `[X]` |
70
- | 7 | inventory-unreliable | step 1 §2 (>20% skill-inventory warnings exceed budget) |
71
- | 8 | recovery-failed | step 5 §1 (durability state insufficient to reconstruct Step 02-04 findings); step 6 §1 (`## Refinement Summary` absent from the compiled document) |
54
+ | **Flags** | `--headless` / `-H`; `--architecture-doc <path>` and `--vs-report-path <path>` answer the step 1 prompts (`--vs-report-path none` refines without a report and skips the search for one); `--scope-skills <names>` (comma-separated skill names that replace the derived scope, so step 2 asks no scope confirmation) |
55
+ | **Gates** | step 1: Input Gate [use args] | step 2: Scope Confirm Gate [C] continue / [X] cancel (only when a derived scope drops skills or keeps an ambiguous one) | step 5: Review Gate [R] review each refinement / [C] approve and replace the refined document / [X] cancel |
56
+ | **Outputs** | `refined-architecture-{arch_project_name}.md` at `{outputFolderPath}` (the document's frontmatter `project_name`, else config's), promoted from a draft once the step 5 review approves it; an earlier one is first renamed to `refined-architecture-{arch_project_name}-{timestamp}.md`. Also `refine-architecture-result-{YYYYMMDD-HHmmss}.json`, its `-latest.json` copy and, once an approved review drops a finding, `.ra-dismissed-{arch_project_name}.json` |
57
+ | **Headless** | Every gate takes its default when `{headless_mode}` is true: `--scope-skills` skips the step 2 scope confirmation, and without `--vs-report-path` step 1 uses the [VS] report it finds. |
72
58
 
73
59
  ## Result Contract (Headless)
74
60
 
75
- 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"`:
76
-
77
- ```
78
- SKF_REFINE_ARCHITECTURE_RESULT_JSON: {"status":"success|error","refined_path":"…|null","gap_count":0,"issue_count":0,"improvement_count":0,"exit_code":0,"halt_reason":null}
79
- ```
80
-
81
- `status` is `"success"` on the terminal happy path, `"error"` on any HALT. `halt_reason` is one of: `null` (success), `"input-missing"`, `"input-invalid"`, `"insufficient-skills"`, `"output-folder-unconfigured"`, `"forge-folder-unconfigured"`, `"inventory-unreliable"`, `"write-failed"`, `"recovery-failed"`, `"user-cancelled"`. `exit_code` matches the table above.
61
+ When `{headless_mode}` is true, step 6 prints one `SKF_REFINE_ARCHITECTURE_RESULT_JSON: {...}` line on **stdout**, and every HARD HALT one on **stderr**, built by the shared emitter: `references/exit-codes.md` gives its fields, the `halt_reason` values and the halt command.
82
62
 
83
63
  ## On Activation
84
64
 
@@ -87,40 +67,42 @@ SKF_REFINE_ARCHITECTURE_RESULT_JSON: {"status":"success|error","refined_path":"
87
67
  - `skills_output_folder`, `forge_data_folder`, `output_folder`, `sidecar_path`
88
68
 
89
69
  2. **Compute run-scoped variables:**
90
- - `timestamp` ← UTC `YYYYMMDD-HHmmss` captured at activation time. Fixed for the entire workflow run; report.md reuses this when writing the result contract.
70
+ - `timestamp` ← the output of `date -u +%Y%m%d-%H%M%S`, run once now: it names the run folder and the copy an earlier refined document is renamed to.
71
+ - `run_dir` ← `{project-root}/_bmad-output/.skf-run/skf-refine-architecture-{timestamp}`, the run folder §5 creates
91
72
 
92
73
  3. **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.
93
74
 
94
75
  4. **Resolve workflow customization.** Run:
95
76
 
96
77
  ```bash
97
- python3 {project-root}/_bmad/scripts/resolve_customization.py \
98
- --skill {skill-root} --key workflow
78
+ uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --project-root {project-root} --key workflow
99
79
  ```
100
80
 
101
- 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-refine-architecture.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. In that case keep the reason as `{customization_resolver_unavailable}` for §5 to record.
102
82
 
103
- - `{skill-root}/customize.toml` — bundled defaults
104
- - `_bmad/custom/<skill-name>.toml` under `{project-root}` — team overrides (committed)
105
- - `_bmad/custom/<skill-name>.user.toml` under `{project-root}` — personal overrides (gitignored)
83
+ Bind each path scalar, taking the bundled default when the merged value is empty or absent:
106
84
 
107
- 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.
85
+ - `{refinementRulesPath}` ← `workflow.refinement_rules_path` if non-empty, else `references/refinement-rules.md` (house style only: the file's first section names what a copy can change)
86
+ - `{outputFolderPath}` ← `workflow.output_folder_path` if non-empty, else `{output_folder}`
87
+ - `{onCompleteCommand}` ← `workflow.on_complete` if non-empty, else empty
108
88
 
109
- Apply the path-scalar fallback now so stage files don't have to repeat the conditional logic. For each scalar, if the merged value is empty or absent, use the bundled default:
89
+ Then 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 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 §5's pre-flight has passed, before §6 loads the first stage.
110
90
 
111
- - `{refinementRulesPath}` ← `workflow.refinement_rules_path` if non-empty, else `references/refinement-rules.md`
112
- - `{outputFolderPath}` ← `workflow.output_folder_path` if non-empty, else `{output_folder}`
113
- - `{onCompleteCommand}` ← `workflow.on_complete` if non-empty, else empty (no-op — report.md skips the hook invocation entirely)
91
+ 5. **Pre-flight: the emitter, config, write probe and run folder.** In that order, so every halt can print its envelope and an empty path halts as missing config (exit 3), not as a write failure.
114
92
 
115
- Stash all three as workflow-context variables. Stage files reference them directly — no conditional at the usage site.
93
+ **The emitter.** Resolve `{emitEnvelopeHelper}` ← `{project-root}/_bmad/skf/shared/scripts/skf-emit-result-envelope.py`, else `{project-root}/src/shared/scripts/skf-emit-result-envelope.py` (the first that exists). If neither exists, HALT (exit code 3, `halt_reason: "resolution-failure"`) at phase `on-activation:emitter` and display only: "Refine Architecture cannot run without `skf-emit-result-envelope.py`, which is not installed. Re-install SKF."
116
94
 
117
- 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), then run `workflow.activation_steps_append` after activation.
95
+ The halts below come before the run folder, so in headless mode each passes its payload on stdin, with `"customization_resolver_unavailable": "<reason>"` added when step 4 kept one:
118
96
 
119
- 5. **Pre-flight config + write probe.** Assert both output paths are configured, then probe writability — order matters: an empty path makes `mkdir -p ""` fail, which would misreport a *missing config* (exit 3) as a *write failure* (exit 4) and collapse the distinction the Result Contract draws.
97
+ ```bash
98
+ uv run {emitEnvelopeHelper} emit-halt --workflow skf-refine-architecture --target stderr <<'SKF_RA_HALT'
99
+ {"phase": "<phase>", "reason": "<the halt message>", "halt_reason": "<halt_reason>"}
100
+ SKF_RA_HALT
101
+ ```
120
102
 
121
- **Config-completeness (exit 3).** If `{outputFolderPath}` is empty: HALT (exit code 3, `halt_reason: "output-folder-unconfigured"`) — "`output_folder` is not configured in config.yaml. Add an `output_folder` path and re-run [RA]." If `{forge_data_folder}` is empty: HALT (exit code 3, `halt_reason: "forge-folder-unconfigured"`) — "`forge_data_folder` is not configured in config.yaml. Add a `forge_data_folder` path and re-run [RA]."
103
+ **Config-completeness (exit 3).** If `{outputFolderPath}` is empty: HALT (exit code 3, `halt_reason: "output-folder-unconfigured"`) at phase `on-activation:config`: "Set `output_folder` in config.yaml, then re-run [RA]." If `{forge_data_folder}` is empty: HALT (exit code 3, `halt_reason: "forge-folder-unconfigured"`) at phase `on-activation:config`: "Set `forge_data_folder` in config.yaml, then re-run [RA]."
122
104
 
123
- **Write probe (exit 4).** With both paths now non-empty, verify each is writable — a read-only mount, full disk, or permissions-denied path otherwise only surfaces at init.md §3c's RA state file write, by which point the user has already gone through input prompts:
105
+ **Write probe (exit 4).** Check that both paths are writable before any prompt:
124
106
 
125
107
  ```bash
126
108
  for dir in "{outputFolderPath}" "{forge_data_folder}"; do
@@ -130,6 +112,14 @@ SKF_REFINE_ARCHITECTURE_RESULT_JSON: {"status":"success|error","refined_path":"
130
112
  done
131
113
  ```
132
114
 
133
- On any non-zero exit: HALT (exit code 4, `halt_reason: "write-failed"`). In headless mode, every HALT above emits the error envelope per **Result Contract (Headless)** with `refined_path: null`.
115
+ On any non-zero exit: HALT (exit code 4, `halt_reason: "write-failed"`) at phase `on-activation:write-probe`, with `"path"` set to the folder that failed.
116
+
117
+ **Run folder (exit 4).** Create the run folder:
118
+
119
+ ```bash
120
+ mkdir -p "{project-root}/_bmad-output/.skf-run" && mkdir "{run_dir}"
121
+ ```
122
+
123
+ 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}." Once it exists and `{customization_resolver_unavailable}` is set, record the reason in the run sink: write `customization_resolver_unavailable: {customization_resolver_unavailable}` to `{run_dir}/resolver-warning.txt` with a file write, never `echo`, then run `uv run {emitEnvelopeHelper} record --run-dir "{run_dir}" --warning "$(cat "{run_dir}/resolver-warning.txt")"`.
134
124
 
135
125
  6. Load, read the full file, and then execute `references/init.md` to begin the workflow.
@@ -1,8 +1,11 @@
1
1
  # DO NOT EDIT -- overwritten on every update.
2
2
  #
3
3
  # Workflow customization surface for skf-refine-architecture.
4
- # Team overrides: _bmad/custom/skf-refine-architecture.toml (under {project-root})
5
- # Personal overrides: _bmad/custom/skf-refine-architecture.user.toml (under {project-root})
4
+ # Team overrides: {project-root}/_bmad/custom/skf-refine-architecture.toml
5
+ # Personal overrides: {project-root}/_bmad/custom/skf-refine-architecture.user.toml
6
+ # The overrides apply only when BMad core's customization resolver runs;
7
+ # otherwise the run warns `customization_resolver_unavailable` and uses the
8
+ # defaults in this file.
6
9
 
7
10
  [workflow]
8
11
 
@@ -10,27 +13,34 @@
10
13
  # scalars: override wins • arrays (persistent_facts, activation_steps_*): append
11
14
  # arrays-of-tables with `code`/`id`: replace matching items, append new ones.
12
15
 
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 architecture refinement work.
16
+ # Steps to run during activation, after the config load and the headless
17
+ # check and before the pre-flight (the emitter, the configured folders, the
18
+ # write probe and the run folder). Overrides append. Use for org-wide checks
19
+ # (auth, network, compliance) that must precede architecture refinement work.
16
20
 
17
21
  activation_steps_prepend = []
18
22
 
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.
23
+ # Steps to run once the pre-flight has passed, before step 1 loads the
24
+ # inputs. Overrides append. Use for context loads or banner customization
25
+ # that should run once activation completes successfully.
22
26
 
23
27
  activation_steps_append = []
24
28
 
25
29
  # Persistent facts the workflow keeps in mind for the whole run
26
- # (refinement standards, evidence-citation rules, house-style preservation
27
- # guardrails). Overrides append.
30
+ # (refinement standards, evidence-citation rules). Overrides append.
28
31
  #
29
- # Each entry is either:
32
+ # Each entry is one of:
30
33
  # - a literal sentence, e.g. "Refinements must cite specific API signatures, never speculate."
31
34
  # - a file reference prefixed with `file:`, e.g.
32
35
  # "file:{project-root}/docs/refine-policy.md" (globs supported; file
33
36
  # contents are loaded and treated as facts).
37
+ # - an entry prefixed with `!`, which loads nothing and drops each earlier
38
+ # entry it names.
39
+ #
40
+ # The default below loads every project-context.md under {project-root}.
41
+ # Overrides append, so they cannot delete it; to stop loading those files,
42
+ # set in {project-root}/_bmad/custom/skf-refine-architecture.toml:
43
+ # persistent_facts = ["!file:{project-root}/**/project-context.md"]
34
44
 
35
45
  persistent_facts = [
36
46
  "file:{project-root}/**/project-context.md",
@@ -38,21 +48,40 @@ persistent_facts = [
38
48
 
39
49
  # --- Optional asset overrides ---
40
50
  #
41
- # Lift the canonical refinement-rules path so orgs can substitute house-style
42
- # rules (e.g. add domain-specific gap categories) without forking the skill.
43
- # Empty string = use the bundled default.
51
+ # House-style refinement rules. Empty = the bundled
52
+ # references/refinement-rules.md. A copy replaces that whole file, so start
53
+ # it from the bundled one: it can add, rename, drop or redefine the gap,
54
+ # issue and improvement types, name its own severity and value tiers, and
55
+ # decide which tier each [VS] verdict raises. It keeps the six tables the
56
+ # steps read by name, and each tier becomes a {<tier>_count} of the
57
+ # Refinement Summary, so step 1 halts on a copy that lacks a table or whose
58
+ # tiers break these rules: a tier name starts with a letter and holds only
59
+ # the letters A to Z, digits and spaces; no two tiers share a name (ignoring
60
+ # case), severity and value tiers included; none is named gap, issue,
61
+ # improvement, unverified or skill; and each VS Report Integration row
62
+ # raises a tier of Issue Severity, or no issue, not both (bold the one it
63
+ # raises). Fixed whatever the copy says: what each step looks for, which
64
+ # skills and pairs are analyzed (the document scope), how findings are
65
+ # stored for recovery (references/finding-storage.md), and how the refined
66
+ # document is built, marked and checked (headings, callouts, RA markers,
67
+ # preservation).
44
68
 
45
69
  refinement_rules_path = ""
46
70
 
47
- # Override the destination directory for the refined architecture document.
48
- # Empty = use {output_folder} from config.yaml. Useful for orgs that want
71
+ # Override the destination directory for the refined architecture document
72
+ # and the files beside it: the earlier refined document a promotion renames,
73
+ # the result files (refine-architecture-result-<YYYYMMDD-HHmmss>.json and its
74
+ # -latest.json copy, the stable path pipelines read) and the record of
75
+ # findings a review dropped (.ra-dismissed-<project>.json). Empty = use
76
+ # {output_folder} from config.yaml. Useful for orgs that want
49
77
  # refined-architecture artifacts to land under a curated docs tree.
50
78
 
51
79
  output_folder_path = ""
52
80
 
53
- # Optional post-completion hook. When non-empty, invoked with
54
- # `--result-path=<path>` after the refined architecture and result JSON are
55
- # finalized (step 6). Use to index the refined doc, notify, or chain the next
56
- # workflow. Failures are logged to workflow_warnings[] but never fail the run.
81
+ # Optional post-completion hook: a shell command. When non-empty, step 6 runs
82
+ # it with `--result-path=<path>` (the per-run result JSON) once the refined
83
+ # architecture is promoted and both result files are written, before the run
84
+ # finishes. Use to index the refined doc, notify, or chain the next workflow.
85
+ # A failure shows as a warning line in step 6's report but never fails the run.
57
86
 
58
87
  on_complete = ""
@@ -1,7 +1,21 @@
1
1
  ---
2
2
  nextStepFile: 'report.md'
3
- # {arch_project_name} resolved in init.md (arch-doc frontmatter project_name, else config project_name).
3
+ refinementRulesData: '{refinementRulesPath}'
4
4
  outputFile: '{outputFolderPath}/refined-architecture-{arch_project_name}.md'
5
+ draftFile: '{forge_data_folder}/.skf-ra-draft-{project_name}.md'
6
+ planFile: '{run_dir}/insertion-plan.json'
7
+ applyResult: '{run_dir}/apply.json'
8
+ promoteResult: '{run_dir}/promote.json'
9
+ preservationScript: 'scripts/skf-check-preservation.py'
10
+ # The findings a review dropped (findingStorageData says how §8 records them).
11
+ dismissedFile: '{outputFolderPath}/.ra-dismissed-{arch_project_name}.json'
12
+ findingStorageData: 'references/finding-storage.md'
13
+ atomicWriteProbeOrder:
14
+ - '{project-root}/_bmad/skf/shared/scripts/skf-atomic-write.py'
15
+ - '{project-root}/src/shared/scripts/skf-atomic-write.py'
16
+ emitEnvelopeProbeOrder:
17
+ - '{project-root}/_bmad/skf/shared/scripts/skf-emit-result-envelope.py'
18
+ - '{project-root}/src/shared/scripts/skf-emit-result-envelope.py'
5
19
  ---
6
20
 
7
21
  <!-- Config: communicate in {communication_language}. Compile the refined architecture document in {document_output_language}. -->
@@ -10,31 +24,39 @@ outputFile: '{outputFolderPath}/refined-architecture-{arch_project_name}.md'
10
24
 
11
25
  ## STEP GOAL:
12
26
 
13
- Produce the refined architecture document by starting with the original as a base, adding gap-fill subsections, issue callout blocks, and improvement suggestions. Append a Refinement Summary. Present for user review before finalizing.
27
+ Stage every finding of Steps 02-04 as an entry of an insertion plan, let the preservation script build the refined document from it as a draft, and present the draft for review; only the review's [C] replaces `{outputFile}`.
14
28
 
15
29
  ## Rules
16
30
 
17
- - Do not discover new gaps, issues, or improvements — use only what Steps 02-04 produced
18
- - Do not delete, reword, or rearrange original architecture content
19
- - Present compiled document for user review (gate checkpoint)
31
+ - Do not discover new gaps, issues, or improvements: use only what Steps 02-04 produced
32
+ - Never write the refined document yourself and never retype the original: `{preservationScript}` copies it, places the plan's blocks, checks that every original line survived and writes the draft
20
33
 
21
34
  ## MANDATORY SEQUENCE
22
35
 
36
+ **Halt envelope.** Every HALT in this step names its exit code, `halt_reason` and phase. In headless mode, stage `{run_dir}/halt.json` as `{"phase": "<phase>", "reason": "<the halt message>", "halt_reason": "<halt_reason>"}`, adding `"path"` when the halt names one, resolve `{emitEnvelopeHelper}` from `{emitEnvelopeProbeOrder}` if it is not bound (first existing path wins), then run:
37
+
38
+ ```bash
39
+ uv run {emitEnvelopeHelper} emit-halt --workflow skf-refine-architecture --run-dir "{run_dir}" --target stderr < "{run_dir}/halt.json"
40
+ ```
41
+
42
+ Display the line it prints, then stop with the halt's exit code (`references/exit-codes.md` describes the envelope). If no candidate exists, or the emitter exits non-zero or prints no line, display the halt message alone. An interactive HALT displays its message and emits nothing.
43
+
23
44
  ### 1. Prepare the Original as Base
24
45
 
25
- Load the complete original architecture document.
46
+ The base is `{architecture_doc}` with any earlier Refine Architecture pass set aside, as Step 01 §1b set it aside in `{analysis_doc}`. §6's script reads `{architecture_doc}` itself; read `{analysis_doc}` only to pick each finding's anchor.
26
47
 
27
- This is the base. Every line of the original appears in the refined document unmodified — the workflow only adds annotations and subsections; dropping or rewording original content silently discards the user's architecture.
48
+ **Context recovery check:** read what is no longer in context from the RA state file: `{run_dir}`, `{timestamp}`, `{architecture_doc}` and `{arch_project_name}` from the `<!-- [RA-RUN] -->` block of `{forge_data_folder}/ra-state-{project_name}.md` (`{analysis_doc}` is `{run_dir}/analysis-doc.md`); the findings of Steps 02-04 from its `<!-- [RA-GAPS] -->`, `<!-- [RA-ISSUES] -->` and `<!-- [RA-IMPROVEMENTS] -->` blocks, and from `<!-- [RA-DISMISSED] -->` when there is one; `{unverified_technologies}` (Step 02 §2b), which the plan (§6) needs: the `<!-- [RA-SCOPE] -->` block; `{vs_report}`, which the VS Coverage row (§5) needs: the `<!-- [RA-VS] -->` block (its `path`, `generatedAt`, `coveragePercentage` and `coverageMeasured`, or `none`). When a block is still missing, or a findings block holds only summary counts, HALT (exit code 8, `halt_reason: "recovery-failed"`) at phase `compile:recovery`: "⚠️ Context for the [Gaps|Issues|Improvements|Scope|VS report] analysis was lost and the state file cannot rebuild it. Re-run [RA] from the beginning: step 01 resets the state file and steps 02-04 rebuild every finding."
28
49
 
29
- **Context recovery check:** If gap, issue, or improvement findings from Steps 02-04 are not available in context (e.g., due to context degradation in long runs), attempt to read the durability state from `{forge_data_folder}/ra-state-{project_name}.md`. Parse the `<!-- [RA-GAPS] -->`, `<!-- [RA-ISSUES] -->`, and `<!-- [RA-IMPROVEMENTS] -->` comment blocks to recover the complete formatted findings (each block contains full citation text with evidence, not just counts). If a section is still missing or contains only summary counts after recovery, HALT (exit code 8, `halt_reason: "recovery-failed"`): "⚠️ Context for the [Gaps|Issues|Improvements] analysis was lost and the durability state is insufficient to reconstruct findings. Re-run [RA] from the beginning — step 01 will reset the state file, then steps 02-04 will rebuild all findings." In headless, emit the error envelope per SKILL.md "Result Contract (Headless)" with `refined_path: null`.
50
+ ### 2. Plan the Gap-Fill Subsections
30
51
 
31
- ### 2. Insert Gap-Fill Subsections
52
+ The insertion plan is one JSON object, written to `{planFile}` at §6 (the script's module docstring gives every field). Each finding becomes one entry of its `entries` list: an `id` (`gap-1`, `issue-1`, `improvement-1` and so on), its `kind` (`gap`, `issue` or `improvement`), the `anchor` that places it, the `skills` its evidence cites, and the `block` to insert. A finding stored under `[RA-DISMISSED]` gets no entry: §7 lists it, and §8 gives it one only when the user takes it back.
32
53
 
33
- For each gap finding from Step 02:
54
+ **Anchors.** An anchor is text copied exactly from one line of `{analysis_doc}`: a heading line such as `## Data Layer`, or the sentence a finding is about. It must occur on exactly one line (a heading anchor matches only a heading of its level and title); when several lines hold it, add `occurrence` (1-based) to pick one. An anchor of `null` sends the entry to its kind's fallback section at the end of the document.
34
55
 
35
- **Locate the most relevant section** in the original architecture where this integration would logically belong.
56
+ For each gap finding from Step 02:
36
57
 
37
- **Insert a gap-fill subsection** one heading level deeper than the parent section:
58
+ - **anchor:** the heading of the section where this integration logically belongs. The script puts the block at the end of that section, one heading level deeper. `null` when no section fits: the script then collects the gap under `## RA: Additional Integration Paths`.
59
+ - **block** (the script sets the heading's level, so any number of `#` will do):
38
60
 
39
61
  ```markdown
40
62
  #### RA: {Library A} <-> {Library B} Integration Path
@@ -48,15 +70,12 @@ For each gap finding from Step 02:
48
70
  {Suggested architecture content describing how the libraries connect}
49
71
  ```
50
72
 
51
- If no clear parent section exists, collect orphan gaps into a new section: "## RA: Additional Integration Paths"
73
+ ### 3. Plan the Issue Annotations
52
74
 
53
- ### 3. Insert Issue Annotations
75
+ For each issue finding from Step 03, with `tier` its severity, a tier of the Issue Severity table of `{refinementRulesData}`:
54
76
 
55
- For each issue finding from Step 03:
56
-
57
- **Locate the section** containing the contradicted claim.
58
-
59
- **Insert an issue callout block** immediately after the contradicted text:
77
+ - **anchor:** the contradicted claim, exactly as Step 03 recorded it from its line of `{analysis_doc}`. The script puts the callout right after the block (paragraph, list, table, blockquote or code fence) that holds the claim. `null` when the claim cannot be located precisely: the script collects such issues under `## RA: Additional Issues Detected`, the most severe tier first.
78
+ - **block:**
60
79
 
61
80
  ```markdown
62
81
  > [!WARNING] **Issue Detected by Refine Architecture** ({severity})
@@ -67,18 +86,15 @@ For each issue finding from Step 03:
67
86
  > **Suggested Correction:** {specific correction with API evidence}
68
87
  ```
69
88
 
70
- **Placement priority:** Place each issue callout immediately after the contradicted text in its original location. If the contradicted claim is inside a Markdown list item, code block, or table row where inserting a callout block would break syntax, place the callout immediately after the enclosing block instead. If the contradicted claim cannot be precisely located, collect into "## RA: Additional Issues Detected" at the end of the document, ordered by severity (Critical first, then Major, then Minor).
71
-
72
- ### 4. Insert Improvement Suggestions
89
+ ### 4. Plan the Improvement Suggestions
73
90
 
74
- For each improvement finding from Step 04:
91
+ For each in-scope improvement finding from Step 04 (the `[RA-IMPROVEMENTS]` findings; out-of-scope improvements and synergies stay under `[RA-OUT-OF-SCOPE]` and never enter the refined document), with `tier` its value, a tier of the Improvement Value table of `{refinementRulesData}`:
75
92
 
76
- **Locate the section** where the library is discussed.
77
-
78
- **Insert an improvement subsection** one heading level deeper:
93
+ - **anchor:** the heading of the section where the library is discussed, also when it appears there only in a table, code block or Mermaid diagram: the script puts the block at the end of that section, one heading level deeper. `null` when no section discusses the library: the script then collects the improvement under `## RA: Additional Improvements Suggested`, the most valuable tier first.
94
+ - **block:**
79
95
 
80
96
  ```markdown
81
- #### RA: Enhancement — {Improvement Title}
97
+ #### RA: Enhancement: {Improvement Title}
82
98
 
83
99
  > [!TIP] **Improvement Suggested by Refine Architecture** ({value} value)
84
100
  > {skill_name} provides `{api}` which is not currently leveraged.
@@ -89,63 +105,90 @@ For each improvement finding from Step 04:
89
105
  {Specific suggestion for updating the architecture}
90
106
  ```
91
107
 
92
- **Order by value:** High value improvements first, then Medium, then Low.
93
-
94
- **Placement fallback:** If the library's only architecture mention is inside a table, code block, or Mermaid diagram where inserting a subsection would break syntax, collect into `## RA: Additional Improvements Suggested` at the end of the document.
95
-
96
108
  ### 5. Add Refinement Summary Section
97
109
 
98
- Append a `## Refinement Summary` section containing:
110
+ The plan's `summary` is the `## Refinement Summary` section, which the script appends last. Leave the count placeholders below as they are: the script fills `{gap_count}`, `{issue_count}`, `{improvement_count}`, a `{<tier>_count}` for each severity and value tier and `{evidence_rows}` from the plan's entries, `{unverified_count}` and `{unverified_technologies}` from its `unverified_technologies`, and `{skill_count}`, and it refuses a summary that types the three totals or holds a placeholder it does not know. Fill the others yourself. The section contains:
99
111
 
100
112
  - **Header:** "Produced by: Refine Architecture workflow using {skill_count} skills" and date
101
- - **Changes Made table** with the following rows:
113
+ - **Changes Made table**, whose Issues Flagged and Improvements Suggested breakdowns name each tier of `{rule_tiers}` (its `issue`, then its `improvement` list) in order, each as `<Tier>: {<tier>_count}`; the rows below show the bundled tiers:
102
114
 
103
115
  | Category | Count | Breakdown |
104
116
  |----------|-------|-----------|
105
- | Gaps Filled | {gap_count} | — |
117
+ | Gaps Filled | {gap_count} | - |
106
118
  | Issues Flagged | {issue_count} | Critical: {critical_count}, Major: {major_count}, Minor: {minor_count} |
107
119
  | Improvements Suggested | {improvement_count} | High: {high_count}, Medium: {medium_count}, Low: {low_count} |
108
- | Skills Used as Evidence | {skill_count} | — |
109
- - **Evidence Sources table:** Each skill name and how many refinements cite it
110
- - **Next Steps:** Review `[!WARNING]` issues, `[!NOTE]` gaps, `[!TIP]` improvements; then run **[SS] Stack Skill** to compose your individual skills into a unified stack skill, providing this refined architecture doc when prompted
120
+ | Skills Used as Evidence | {skill_count} | - |
121
+ | Not verified (no skill) | {unverified_count} | {unverified_technologies} |
122
+ | VS Coverage | {vs_coverage} | technologies with a skill when [VS] ran, from `{vs_report_name}` |
123
+
124
+ The Not verified (no skill) row is always written: its Breakdown names the technologies comma-separated, or reads `none`. Write the VS Coverage row only when a VS report was used (`vs_report_available` is true), from the report JSON Step 01 §1 cached (`{vs_report}`), never from the report file: `{vs_coverage}` is its `coveragePercentage` followed by `%` when its `coverageMeasured` is true, and `not recorded` when `coverageMeasured` is false. `{vs_report_name}` is the file name of the JSON's `path`: the refined document is shared, so it names no folder.
125
+
126
+ - **Evidence Sources table:** a `| Skill | Refinements |` header row and its separator, then `{evidence_rows}` (the script writes one row per cited skill)
127
+ - **Next Steps:** Review `[!WARNING]` issues, `[!NOTE]` gaps, `[!TIP]` improvements; then run **[SS] Stack Skill** to compose your individual skills into a unified stack skill, providing this refined architecture doc when prompted. When `{unverified_technologies}` is not empty, add one line before [SS] that names them: nothing checked what the architecture says about them, so generate their skills with **[CS] Create Skill** or **[QS] Quick Skill** and re-run **[RA]** first.
111
128
 
112
- ### 6. Write the Refined Document
129
+ ### 6. Build the Draft
130
+
131
+ Write the plan to `{planFile}`: the `entries` of §2 to §4, the `summary` of §5, `unverified_technologies` (Step 02 §2b's list as written in the document, `[]` when it is empty), `skill_count` (the inventory's `{skill_count}`, Step 01 §2) and `tiers` (`{"issue": [...], "improvement": [...]}`: `{rule_tiers}`, the `tiers` Step 01 §4's `rules` check printed; run that command again if they are no longer in context). Then run:
132
+
133
+ ```bash
134
+ uv run {preservationScript} apply --original "{architecture_doc}" --plan "{planFile}" --draft "{draftFile}" -o "{applyResult}"
135
+ ```
113
136
 
114
- Write the complete refined architecture to `{outputFile}`.
137
+ Branch on its exit code:
115
138
 
116
- On any write failure (read-only mount, disk full, permissions denied): HALT (exit code 4, `halt_reason: "write-failed"`) with the captured error. In headless, emit the error envelope per SKILL.md "Result Contract (Headless)" with `refined_path: null`. The On-Activation §5 write probe should have caught an unwritable output folder earlier — if it surfaces here, the filesystem state changed mid-workflow.
139
+ - **0:** the draft is written and the check passed. `{applyResult}` holds its `counts`, `evidence`, filled `summary`, `unverified_technologies` and `set_aside` (the earlier pass's blocks), where §7 and Step 06 take every number and name.
140
+ - **1 with `status: "problems"`:** nothing was written. Each entry of `problems[]` names the plan entry (`id`), the `reason` and what to change (an anchor's `closest` line or its `matches`, of which `occurrence` can pick one). Fix the plan and run the command again; an anchor still not found after one fix becomes `null`.
141
+ - **1 with `status: "not-preserved"`:** the draft would lose or change a line of the original, so nothing was written (an earlier draft stays as it was), and running the same plan again gives the same result. Show the first entry of `missing[]` and of `altered[]`. In headless, HALT (exit code 4, `halt_reason: "preservation-failed"`) at phase `compile:draft` without a retry, naming that first line; in an interactive run, show the failure at §7 and offer no [C] until a feedback round's `apply` passes.
142
+ - **2** with a JSON (`error` names the file it could not read): for `{planFile}`, write the plan again; for `{architecture_doc}`, HALT (exit code 2, `halt_reason: "input-invalid"`) at phase `compile:draft`, with `"path"` set to it. **2 with no JSON:** a malformed call: fix it and run it again.
143
+ - **3:** the draft could not be written: HALT (exit code 4, `halt_reason: "write-failed"`) at phase `compile:draft`, naming its `error`, with `"path": "{draftFile}"`.
144
+ - If `uv` cannot start the script, here or for §8's `promote`: HALT (exit code 3, `halt_reason: "resolution-failure"`) at phase `compile:draft` (`compile:promote` for `promote`).
117
145
 
118
- ### 7. Present Compiled Document for Review
146
+ `{outputFile}` is not touched here: an earlier refined document stays as it is until §8's [C].
147
+
148
+ ### 7. Present the Draft for Review
119
149
 
120
150
  "**Refined architecture compiled. Please review:**
121
151
 
122
152
  ---
123
153
 
124
- {Display the Refinement Summary section only — not the full document}
154
+ {Display the `summary` of `{applyResult}`: the Refinement Summary as the draft holds it}
125
155
 
126
156
  ---
127
157
 
128
- **The full refined document has been written to:** `{outputFile}`
158
+ {IF the `[RA-DISMISSED]` block holds findings:}**Left out, as a review dropped them from an earlier refinement of this document.** Ask for one back to insert it:
159
+ {One line per finding: its kind, its skills, its own title and the title of the record it matched}
160
+
161
+ **The draft is at:** `{draftFile}`. {IF `{outputFile}` exists: `{outputFile}` still holds your earlier refined document; approving renames it with this run's timestamp before the draft takes its place.}{ELSE: Approving writes it to `{outputFile}`.} Ask for changes here rather than editing the draft: each feedback round rebuilds it.
129
162
 
130
- Please review the refinements:
131
- - {gap_count} gap-fill subsections added
132
- - {issue_count} issue annotations inserted
133
- - {improvement_count} improvement suggestions included
134
- - Original architecture content preserved in full
163
+ - {IF the last `apply` failed the check:}The draft would lose or change line {the first `missing[]` or `altered[]` line} of the original: [C] waits for a draft that passes{ELSE IF its `set_aside` holds a `legacy` entry:}Every original line is preserved except lines {ranges} of `{architecture_doc}` (each `legacy` entry's `start`-`end`), which an earlier pass left without RA markers: they were set aside unchecked, so text of your own there is not in the draft{ELSE:}Original architecture content preserved in full: the preservation script found every line unchanged{END IF}
164
+ {IF previous_pass:}- The earlier Refine Architecture pass in this document was set aside, and these refinements replace it
135
165
 
136
- **Does the refinement look correct?**"
166
+ **Does the refinement look correct?** Choose [R] to walk through each refinement with its evidence, or tell me what to change, such as a finding to drop."
137
167
 
138
168
  ### 8. Present MENU OPTIONS
139
169
 
140
- Display: **Select:** [C] Continue to Final Report | [X] Cancel
170
+ Display: **Select:** [R] Review each refinement | [C] Approve and replace the refined document | [X] Cancel
141
171
 
142
172
  #### GATE [default: C]
143
173
 
144
- This is a review gate: halt for the user's decision and do not chain onward until they approve — an unreviewed compile ships un-vetted refinements. Headless auto-selects [C] (log: "headless: auto-approve compiled architecture").
174
+ Wait for the user's choice. Headless auto-selects [C] (log: "headless: auto-approve compiled architecture") and records that decision in the run sink the moment it is taken: stage `{run_dir}/decision.json` as `{"gate": "compile.review", "default_action": "C", "taken_action": "C", "reason": "headless: auto-approve compiled architecture", "evidence": {"draft": "{draftFile}", "output": "{outputFile}"}}`, then run:
175
+
176
+ ```bash
177
+ uv run {emitEnvelopeHelper} record --workflow skf-refine-architecture --run-dir "{run_dir}" --decision < "{run_dir}/decision.json"
178
+ ```
145
179
 
146
180
  #### Menu Handling Logic:
147
181
 
148
- - IF C: Load, read entire file, then execute {nextStepFile}
149
- - IF cancel / exit / [X] / q / :q: HALT (exit code 6, `halt_reason: "user-cancelled"`) — display "Cancelled — refinement not finalized." In headless, emit the error envelope per SKILL.md "Result Contract (Headless)" with `refined_path: null`. These global cancel tokens pre-empt the feedback branch below.
150
- - IF Any other: Process as feedback, adjust specific refinements in the document, rewrite {outputFile}, redisplay preview, then [Redisplay Menu Options](#8-present-menu-options)
182
+ - IF R: walk through each refinement with its evidence and its plan `id`, so feedback can name it: the gaps, the issues by severity, the improvements by value, then the findings left out as previously dismissed. It changes nothing; then redisplay this menu.
183
+ - IF C (only while the last `apply` exited 0): promote the draft. The script checks it once more, renames a file already at `{outputFile}` to `refined-architecture-{arch_project_name}-{timestamp}.md` (or a free `-2` name), and moves the draft there:
184
+
185
+ ```bash
186
+ uv run {preservationScript} promote --original "{architecture_doc}" --draft "{draftFile}" --output "{outputFile}" --timestamp "{timestamp}" -o "{promoteResult}"
187
+ ```
151
188
 
189
+ - **0:** the draft is now `{outputFile}`, and `{promoteResult}` records `previous`, the name the earlier refined document took (null when there was none). When a feedback round staged `{run_dir}/dismissed.json`, only now write it to `{dismissedFile}`, as `{findingStorageData}` says. Then load, read the entire file, and execute `{nextStepFile}`.
190
+ - **1** (`not-preserved`): nothing was moved. Show the first entry of `missing[]` or `altered[]`, rebuild once with §6's `apply`, and promote again. If it fails the same way, HALT (exit code 4, `halt_reason: "preservation-failed"`) at phase `compile:promote`, naming that line: the draft stays at `{draftFile}` and `{outputFile}` is as it was.
191
+ - **2** with a JSON (`error` names the file it could not read): for the draft, rebuild it once and promote again, and if it still cannot be read, HALT (exit code 4, `halt_reason: "write-failed"`) at phase `compile:promote`, with `"path": "{draftFile}"`; for `{architecture_doc}`, HALT (exit code 2, `halt_reason: "input-invalid"`) at phase `compile:promote`, with `"path"` set to it. **2 with no JSON:** fix the malformed call and run it again.
192
+ - **3:** HALT (exit code 4, `halt_reason: "write-failed"`) at phase `compile:promote`, naming its `error`, with `"path": "{outputFile}"`. `{outputFile}` is as it was unless the `error` names a file the script could not put back.
193
+ - IF cancel / exit / [X] / q / :q: delete the draft (`rm -f "{draftFile}"`), display "Cancelled: refinement not finalized. `{outputFile}` is unchanged." and HALT (exit code 6, `halt_reason: "user-cancelled"`) at phase `compile:review`. These global cancel tokens pre-empt the feedback branch below.
194
+ - IF Any other: process it as feedback on the plan: in `{planFile}`, change the anchor, tier or block of the entries it names, drop an entry the user rejects, or add one (as §2 to §4 would) for a dismissed finding the user takes back, and record each drop or take-back in `{run_dir}/dismissed.json` as `{findingStorageData}` says. Then run §6's `apply` again: it rebuilds the draft from the original, so feedback never edits the draft. On exit 0, redisplay §7; on a failure, handle it as §6 says (the previous draft stays), and [C] waits for a round whose `apply` passes. Then [Redisplay Menu Options](#8-present-menu-options)
@@ -0,0 +1,30 @@
1
+ # Exit Codes and Result Envelope
2
+
3
+ Every hard halt in this workflow exits with a stable code so headless automators can branch on the failure class without grepping message text. Each code pairs with a `halt_reason` string carried in the headless result envelope.
4
+
5
+ | Code | Meaning | Raised by |
6
+ | ---- | -------------------- | -------------------------------------------------------------------------------------------- |
7
+ | 0 | success | step 7 (terminal) |
8
+ | 2 | input-missing / input-invalid | step 1 §1 (headless with no `--architecture-doc`) → `input-missing`; step 1 §1 (an architecture document that is missing or unreadable, or a [VS] report that breaks the feasibility-report contract (`schemaVersion` not `1.0`, a section missing or out of order, a missing or second verdict table, an unknown verdict token) or cannot be read), step 1 §1b and step 5 §6 and §8 (the architecture document cannot be read as UTF-8 text) → `input-invalid` |
9
+ | 3 | resolution-failure | On Activation §5 (`output_folder` or `forge_data_folder` unconfigured → `output-folder-unconfigured` / `forge-folder-unconfigured`; the result emitter is not installed → `resolution-failure`); a helper is not installed, cannot start or fails: step 1 §2 (`skf-enumerate-stack-skills.py`, phase `init:inventory`), step 2 §2 (`skf-comention-pairs.py`, phase `gap-analysis:comention`); a helper is not installed or `uv` cannot start it: step 1 §1 (`skf-validate-feasibility-report.py`, phase `init:feasibility-validator`), step 1 §1b, step 3 §4, step 5 §6 and §8 and step 6 §1 (`scripts/skf-check-preservation.py`, or at step 3 §4 the shared feasibility-report reader it runs) → `resolution-failure`; step 1 §4 (the refinement rules cannot be read, lack a table the steps read or name a tier the Refinement Summary cannot count) → `resolution-failure` |
10
+ | 4 | write-failure | On Activation §5 (the write probe, the run folder); step 1 §1b (the analysis copy); step 1 §3c (the RA state file); step 5 §6 (the draft) and §8 (the promotion, or a draft that still cannot be read after one rebuild); step 6 §1 (the result payload) and §4 (the emitter refuses it twice) → `write-failed`; step 5 §6 (in headless, the draft would lose or change a line of the original) and §8 (it still would after one rebuild) → `preservation-failed` |
11
+ | 5 | state-conflict | step 1 §3 (no skill SKF generated was found: refinement requires ≥1 skill) → `insufficient-skills` |
12
+ | 6 | user-cancelled | step 1 §1 prompt cancelled; step 2 §2b scope confirmation `[X]`; any prompt that accepted `cancel`/`exit`/`:q`; step 5 review gate `[X]` (the draft is deleted, `{outputFile}` is unchanged) |
13
+ | 7 | inventory-unreliable | step 1 §2 (skill-inventory warnings exceed the failure budget); skills SKF did not generate are not counted |
14
+ | 8 | recovery-failed | step 3 §4 (the [VS] report cannot be read again, or [VS] rewrote it during the run, or the refinement rules no longer pass step 1's check); step 5 §1 (the saved state is not enough to rebuild the Step 02-04 findings, the scope or the VS report); step 6 §1 (a record of the draft's build or promotion is missing) |
15
+
16
+ ## Result Envelope
17
+
18
+ When `{headless_mode}` is true, step 6 prints one `SKF_REFINE_ARCHITECTURE_RESULT_JSON: {...}` line on **stdout** when it writes the result contract, and every HARD HALT prints one on **stderr** with `status: "error"`. The shared emitter builds each line from the payload the stage stages in `{run_dir}`, folds in the decisions and warnings the run recorded there, and checks it against `{project-root}/_bmad/skf/shared/scripts/schemas/skf-refine-architecture-result-envelope.v1.json` (`{project-root}/src/shared/scripts/schemas/skf-refine-architecture-result-envelope.v1.json` in a dev checkout), whose descriptions say what each field holds: `status`, `refined_path`, `previous_refined_path`, `previous_pass`, `gap_count`, `issue_count`, `improvement_count`, `unverified_count`, `exit_code`, `halt_reason`, `run_id`, `result_path`, and `headless_decisions`, `warnings` and `error` when they apply. Never type the line yourself.
19
+
20
+ `status` is `"success"` on the terminal happy path, `"error"` on any HALT. `halt_reason` is one of: `null` (success), `"input-missing"`, `"input-invalid"`, `"insufficient-skills"`, `"output-folder-unconfigured"`, `"forge-folder-unconfigured"`, `"resolution-failure"`, `"inventory-unreliable"`, `"write-failed"`, `"preservation-failed"`, `"recovery-failed"`, `"user-cancelled"`. `exit_code` matches the table above, and the emitter derives it from `halt_reason`.
21
+
22
+ ## Emitting a Halt
23
+
24
+ Every HALT names its exit code, `halt_reason` and phase. In headless mode, stage `{run_dir}/halt.json` as `{"phase": "<phase>", "reason": "<the halt message>", "halt_reason": "<halt_reason>"}`, adding `"refined_path": "{outputFile}"` once step 5 promoted the draft and `"path"` when the halt names one, then run:
25
+
26
+ ```bash
27
+ uv run {emitEnvelopeHelper} emit-halt --workflow skf-refine-architecture --run-dir "{run_dir}" --target stderr < "{run_dir}/halt.json"
28
+ ```
29
+
30
+ Each stage that halts shows this command and the probe order that resolves `{emitEnvelopeHelper}`, so a late halt emits the right line even when this file is not in context. Display the line it prints, then stop with the halt's exit code. If the emitter exits non-zero or prints no line, display the halt message alone. An interactive HALT displays its message and emits nothing. A HALT before the run folder exists (SKILL.md On Activation §5) passes the payload on stdin instead.