bmad-module-skill-forge 1.9.0 → 2.0.1

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 (281) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.nvmrc +1 -1
  3. package/README.md +10 -5
  4. package/docs/_data/pinned.yaml +2 -2
  5. package/docs/agents.md +11 -2
  6. package/docs/architecture.md +5 -4
  7. package/docs/bmad-synergy.md +30 -7
  8. package/docs/campaign.md +172 -0
  9. package/docs/examples.md +7 -3
  10. package/docs/forge-auto.md +90 -0
  11. package/docs/getting-started.md +9 -0
  12. package/docs/how-it-works.md +6 -4
  13. package/docs/index.md +4 -3
  14. package/docs/skill-model.md +1 -1
  15. package/docs/troubleshooting.md +17 -1
  16. package/docs/verifying-a-skill.md +2 -2
  17. package/docs/why-skf.md +1 -1
  18. package/docs/workflows.md +64 -24
  19. package/package.json +2 -2
  20. package/src/knowledge/skill-lifecycle.md +1 -1
  21. package/src/module-help.csv +4 -3
  22. package/src/shared/data/language-corpora.json +32 -0
  23. package/src/shared/references/pipeline-contracts.md +6 -3
  24. package/src/shared/scripts/schemas/skill-brief.v1.json +6 -1
  25. package/src/shared/scripts/skf-comention-pairs.py +350 -0
  26. package/src/shared/scripts/skf-count-tokens.py +222 -0
  27. package/src/shared/scripts/skf-derive-assembly-shape.py +107 -0
  28. package/src/shared/scripts/skf-detect-docs.py +240 -4
  29. package/src/shared/scripts/skf-detect-language.py +82 -3
  30. package/src/shared/scripts/skf-detect-tools.py +105 -2
  31. package/src/shared/scripts/skf-emit-result-envelope.py +17 -0
  32. package/src/shared/scripts/skf-enumerate-stack-skills.py +111 -2
  33. package/src/shared/scripts/skf-extract-public-api.py +53 -0
  34. package/src/shared/scripts/skf-find-cycles.py +246 -0
  35. package/src/shared/scripts/skf-hash-content.py +487 -2
  36. package/src/shared/scripts/skf-language-corpora.py +100 -0
  37. package/src/shared/scripts/skf-manifest-ops.py +67 -1
  38. package/src/shared/scripts/skf-merge-doc-urls.py +244 -0
  39. package/src/shared/scripts/skf-preapply.py +1 -1
  40. package/src/shared/scripts/skf-rebuild-managed-sections.py +180 -0
  41. package/src/shared/scripts/skf-recommend-scope-type.py +1 -2
  42. package/src/shared/scripts/skf-render-metadata-stats.py +499 -0
  43. package/src/shared/scripts/skf-rewrite-skill-name.py +308 -0
  44. package/src/shared/scripts/skf-shape-detect.py +576 -25
  45. package/src/shared/scripts/skf-shard-body.py +461 -0
  46. package/src/shared/scripts/skf-skill-inventory.py +139 -3
  47. package/src/shared/scripts/skf-structural-diff.py +307 -67
  48. package/src/shared/scripts/skf-validate-brief-schema.py +41 -6
  49. package/src/shared/scripts/skf-validate-feasibility-report.py +234 -0
  50. package/src/shared/scripts/skf-validate-frontmatter.py +17 -12
  51. package/src/shared/scripts/skf-validate-output.py +443 -10
  52. package/src/shared/scripts/skf-validate-pins.py +3 -3
  53. package/src/shared/scripts/skf-verify-no-trace.py +214 -0
  54. package/src/shared/scripts/skf-verify-provenance-completeness.py +439 -0
  55. package/src/shared/scripts/skf-write-skill-brief.py +21 -5
  56. package/src/skf-analyze-source/SKILL.md +17 -32
  57. package/src/skf-analyze-source/assets/skill-brief-schema.md +1 -1
  58. package/src/skf-analyze-source/customize.toml +2 -0
  59. package/src/skf-analyze-source/references/auto-docs-only.md +116 -0
  60. package/src/skf-analyze-source/references/continue.md +8 -13
  61. package/src/skf-analyze-source/references/generate-briefs.md +28 -12
  62. package/src/skf-analyze-source/references/headless-contract.md +33 -0
  63. package/src/skf-analyze-source/references/health-check.md +1 -2
  64. package/src/skf-analyze-source/references/identify-units.md +25 -36
  65. package/src/skf-analyze-source/references/init.md +12 -25
  66. package/src/skf-analyze-source/references/map-and-detect.md +8 -20
  67. package/src/skf-analyze-source/references/recommend.md +4 -14
  68. package/src/skf-analyze-source/references/scan-project.md +3 -11
  69. package/src/skf-analyze-source/references/step-auto-scope.md +211 -197
  70. package/src/skf-analyze-source/references/step-shape-detect.md +20 -13
  71. package/src/skf-analyze-source/references/unit-detection-heuristics.md +2 -2
  72. package/src/skf-audit-skill/SKILL.md +9 -6
  73. package/src/skf-audit-skill/customize.toml +2 -0
  74. package/src/skf-audit-skill/references/init.md +58 -32
  75. package/src/skf-audit-skill/references/re-index.md +15 -34
  76. package/src/skf-audit-skill/references/report.md +11 -58
  77. package/src/skf-audit-skill/references/semantic-diff.md +4 -22
  78. package/src/skf-audit-skill/references/severity-classify.md +53 -87
  79. package/src/skf-audit-skill/references/step-doc-drift.md +49 -19
  80. package/src/skf-audit-skill/references/structural-diff.md +43 -68
  81. package/src/skf-brief-skill/SKILL.md +7 -36
  82. package/src/skf-brief-skill/assets/scope-templates.md +1 -1
  83. package/src/skf-brief-skill/assets/skill-brief-schema.md +1 -1
  84. package/src/skf-brief-skill/customize.toml +14 -0
  85. package/src/skf-brief-skill/references/analyze-target.md +13 -18
  86. package/src/skf-brief-skill/references/confirm-brief.md +2 -15
  87. package/src/skf-brief-skill/references/draft-checkpoint.md +8 -8
  88. package/src/skf-brief-skill/references/gather-intent.md +27 -24
  89. package/src/skf-brief-skill/references/headless-args.md +1 -1
  90. package/src/skf-brief-skill/references/health-check.md +1 -22
  91. package/src/skf-brief-skill/references/invocation-contract.md +37 -0
  92. package/src/skf-brief-skill/references/scope-definition.md +6 -15
  93. package/src/skf-brief-skill/references/step-auto-brief.md +22 -9
  94. package/src/skf-brief-skill/references/step-auto-validate.md +3 -7
  95. package/src/skf-brief-skill/references/version-resolution.md +1 -1
  96. package/src/skf-brief-skill/references/write-brief.md +19 -13
  97. package/src/skf-campaign/SKILL.md +121 -0
  98. package/src/skf-campaign/assets/campaign-state-schema.json +191 -0
  99. package/src/skf-campaign/customize.toml +75 -0
  100. package/src/skf-campaign/manifest.yaml +15 -0
  101. package/src/skf-campaign/references/campaign-contracts.md +67 -0
  102. package/src/skf-campaign/references/campaign-directive-spec.md +32 -0
  103. package/src/skf-campaign/references/health-check.md +35 -0
  104. package/src/skf-campaign/references/step-01-setup.md +121 -0
  105. package/src/skf-campaign/references/step-02-strategy.md +102 -0
  106. package/src/skf-campaign/references/step-03-pins.md +56 -0
  107. package/src/skf-campaign/references/step-04-provenance.md +63 -0
  108. package/src/skf-campaign/references/step-05-skill-loop.md +103 -0
  109. package/src/skf-campaign/references/step-06-batch.md +88 -0
  110. package/src/skf-campaign/references/step-07-capstone.md +63 -0
  111. package/src/skf-campaign/references/step-08-verify.md +75 -0
  112. package/src/skf-campaign/references/step-09-refine.md +83 -0
  113. package/src/skf-campaign/references/step-10-export.md +106 -0
  114. package/src/skf-campaign/references/step-11-maintenance.md +84 -0
  115. package/src/skf-campaign/references/step-resume.md +115 -0
  116. package/src/skf-campaign/scripts/.gitkeep +0 -0
  117. package/src/skf-campaign/scripts/campaign-deps.py +244 -0
  118. package/src/skf-campaign/scripts/campaign-parse-manifest.py +119 -0
  119. package/src/skf-campaign/scripts/campaign-provenance.py +247 -0
  120. package/src/skf-campaign/scripts/campaign-render-batch.py +199 -0
  121. package/src/skf-campaign/scripts/campaign-render-kickoff.py +158 -0
  122. package/src/skf-campaign/scripts/campaign-report.py +249 -0
  123. package/src/skf-campaign/scripts/campaign-status.py +162 -0
  124. package/src/skf-campaign/scripts/campaign-validate-pins.py +174 -0
  125. package/src/skf-campaign/scripts/campaign-validate-state.py +207 -0
  126. package/src/skf-campaign/templates/campaign-brief-template.yaml +34 -0
  127. package/src/skf-campaign/templates/campaign-report-template.md +54 -0
  128. package/src/skf-campaign/templates/kickoff-template.md +48 -0
  129. package/src/skf-create-skill/SKILL.md +15 -4
  130. package/src/skf-create-skill/assets/compile-assembly-rules.md +35 -34
  131. package/src/skf-create-skill/assets/skill-sections.md +9 -100
  132. package/src/skf-create-skill/assets/tessl-dismissal-rules.md +4 -13
  133. package/src/skf-create-skill/customize.toml +13 -0
  134. package/src/skf-create-skill/references/authoritative-files-protocol.md +7 -7
  135. package/src/skf-create-skill/references/compile.md +37 -47
  136. package/src/skf-create-skill/references/component-extraction.md +8 -35
  137. package/src/skf-create-skill/references/ecosystem-check.md +9 -25
  138. package/src/skf-create-skill/references/enrich.md +4 -17
  139. package/src/skf-create-skill/references/extract.md +20 -27
  140. package/src/skf-create-skill/references/extraction-patterns-tracing.md +1 -1
  141. package/src/skf-create-skill/references/extraction-patterns.md +10 -8
  142. package/src/skf-create-skill/references/generate-artifacts.md +20 -25
  143. package/src/skf-create-skill/references/health-check.md +2 -2
  144. package/src/skf-create-skill/references/load-brief.md +16 -18
  145. package/src/skf-create-skill/references/report.md +27 -14
  146. package/src/skf-create-skill/references/source-resolution-protocols.md +4 -4
  147. package/src/skf-create-skill/references/step-auto-shard.md +52 -25
  148. package/src/skf-create-skill/references/step-doc-rot.md +33 -15
  149. package/src/skf-create-skill/references/step-doc-sources.md +13 -4
  150. package/src/skf-create-skill/references/sub/ccc-discover.md +2 -13
  151. package/src/skf-create-skill/references/sub/fetch-docs.md +33 -46
  152. package/src/skf-create-skill/references/sub/fetch-temporal.md +5 -20
  153. package/src/skf-create-skill/references/tier-degradation-rules.md +6 -8
  154. package/src/skf-create-skill/references/validate.md +69 -29
  155. package/src/skf-create-skill/scripts/scan-doc-rot.py +245 -0
  156. package/src/skf-create-stack-skill/SKILL.md +15 -9
  157. package/src/skf-create-stack-skill/assets/provenance-map-schema.md +1 -1
  158. package/src/skf-create-stack-skill/customize.toml +10 -0
  159. package/src/skf-create-stack-skill/references/compile-stack.md +7 -8
  160. package/src/skf-create-stack-skill/references/compose-mode-rules.md +2 -13
  161. package/src/skf-create-stack-skill/references/detect-integrations.md +49 -54
  162. package/src/skf-create-stack-skill/references/detect-manifests.md +37 -30
  163. package/src/skf-create-stack-skill/references/generate-output.md +24 -75
  164. package/src/skf-create-stack-skill/references/init.md +9 -81
  165. package/src/skf-create-stack-skill/references/manifest-patterns.md +5 -35
  166. package/src/skf-create-stack-skill/references/parallel-extract.md +12 -27
  167. package/src/skf-create-stack-skill/references/rank-and-confirm.md +6 -6
  168. package/src/skf-create-stack-skill/references/report.md +27 -62
  169. package/src/skf-create-stack-skill/references/validate.md +35 -31
  170. package/src/skf-drop-skill/SKILL.md +20 -23
  171. package/src/skf-drop-skill/customize.toml +10 -0
  172. package/src/skf-drop-skill/references/execute.md +67 -36
  173. package/src/skf-drop-skill/references/headless-contract.md +18 -0
  174. package/src/skf-drop-skill/references/health-check.md +1 -13
  175. package/src/skf-drop-skill/references/report.md +44 -10
  176. package/src/skf-drop-skill/references/select.md +93 -48
  177. package/src/skf-drop-skill/scripts/dir-sizes.py +116 -0
  178. package/src/skf-export-skill/SKILL.md +17 -14
  179. package/src/skf-export-skill/assets/managed-section-format.md +2 -5
  180. package/src/skf-export-skill/customize.toml +10 -6
  181. package/src/skf-export-skill/references/generate-snippet.md +21 -35
  182. package/src/skf-export-skill/references/load-skill.md +44 -42
  183. package/src/skf-export-skill/references/multi-skill-mode.md +1 -1
  184. package/src/skf-export-skill/references/orphan-context-detection.md +11 -3
  185. package/src/skf-export-skill/references/package.md +27 -33
  186. package/src/skf-export-skill/references/preflight-snippet-root-probe.md +24 -5
  187. package/src/skf-export-skill/references/result-envelope.md +28 -0
  188. package/src/skf-export-skill/references/summary.md +11 -5
  189. package/src/skf-export-skill/references/token-report.md +42 -24
  190. package/src/skf-export-skill/references/update-context.md +32 -33
  191. package/src/skf-forger/SKILL.md +32 -39
  192. package/src/skf-forger/references/pipeline-mode.md +34 -0
  193. package/src/skf-forger/scripts/parse-pipeline.py +270 -0
  194. package/src/skf-quick-skill/SKILL.md +10 -60
  195. package/src/skf-quick-skill/customize.toml +9 -0
  196. package/src/skf-quick-skill/references/batch-mode.md +6 -4
  197. package/src/skf-quick-skill/references/compile.md +15 -52
  198. package/src/skf-quick-skill/references/ecosystem-check.md +5 -20
  199. package/src/skf-quick-skill/references/finalize.md +12 -6
  200. package/src/skf-quick-skill/references/halt-contract.md +54 -0
  201. package/src/skf-quick-skill/references/health-check.md +3 -4
  202. package/src/skf-quick-skill/references/quick-extract.md +7 -18
  203. package/src/skf-quick-skill/references/registry-resolution.md +1 -23
  204. package/src/skf-quick-skill/references/resolve-target.md +27 -34
  205. package/src/skf-quick-skill/references/write-and-validate.md +10 -25
  206. package/src/skf-refine-architecture/SKILL.md +16 -8
  207. package/src/skf-refine-architecture/customize.toml +9 -0
  208. package/src/skf-refine-architecture/references/compile.md +10 -8
  209. package/src/skf-refine-architecture/references/gap-analysis.md +21 -50
  210. package/src/skf-refine-architecture/references/health-check.md +1 -1
  211. package/src/skf-refine-architecture/references/improvements.md +9 -25
  212. package/src/skf-refine-architecture/references/init.md +9 -16
  213. package/src/skf-refine-architecture/references/issue-detection.md +10 -25
  214. package/src/skf-refine-architecture/references/refinement-rules.md +4 -16
  215. package/src/skf-refine-architecture/references/report.md +14 -11
  216. package/src/skf-rename-skill/SKILL.md +11 -21
  217. package/src/skf-rename-skill/customize.toml +10 -0
  218. package/src/skf-rename-skill/references/execute.md +112 -82
  219. package/src/skf-rename-skill/references/exit-codes.md +12 -0
  220. package/src/skf-rename-skill/references/report.md +16 -8
  221. package/src/skf-rename-skill/references/select.md +69 -42
  222. package/src/skf-rename-skill/scripts/skf-validate-rename-name.py +161 -0
  223. package/src/skf-setup/SKILL.md +21 -13
  224. package/src/skf-setup/customize.toml +10 -0
  225. package/src/skf-setup/references/auto-index.md +11 -10
  226. package/src/skf-setup/references/ccc-index.md +14 -15
  227. package/src/skf-setup/references/detect-and-tier.md +10 -8
  228. package/src/skf-setup/references/report.md +26 -32
  229. package/src/skf-setup/references/tier-rules.md +2 -32
  230. package/src/skf-setup/references/write-config.md +9 -10
  231. package/src/skf-test-skill/SKILL.md +10 -8
  232. package/src/skf-test-skill/customize.toml +2 -0
  233. package/src/skf-test-skill/references/coherence-check.md +19 -31
  234. package/src/skf-test-skill/references/coverage-check.md +111 -67
  235. package/src/skf-test-skill/references/detect-mode.md +10 -41
  236. package/src/skf-test-skill/references/external-validators.md +11 -19
  237. package/src/skf-test-skill/references/init.md +39 -21
  238. package/src/skf-test-skill/references/migration-section-rules.md +4 -4
  239. package/src/skf-test-skill/references/report.md +60 -40
  240. package/src/skf-test-skill/references/score.md +32 -64
  241. package/src/skf-test-skill/references/scoring-rules.md +6 -62
  242. package/src/skf-test-skill/references/source-access-protocol.md +15 -5
  243. package/src/skf-test-skill/references/step-hard-gate.md +1 -3
  244. package/src/skf-test-skill/scripts/aggregate-coherence.py +276 -0
  245. package/src/skf-test-skill/scripts/check-metadata-coherence.py +359 -0
  246. package/src/skf-test-skill/scripts/combine-external-scores.py +190 -0
  247. package/src/skf-test-skill/scripts/compute-score.py +135 -4
  248. package/src/skf-test-skill/scripts/reconcile-coverage.py +327 -0
  249. package/src/skf-test-skill/scripts/validate-inventory.py +251 -0
  250. package/src/skf-test-skill/scripts/verify-declared-numerator.py +192 -0
  251. package/src/skf-update-skill/SKILL.md +17 -5
  252. package/src/skf-update-skill/customize.toml +11 -6
  253. package/src/skf-update-skill/references/detect-changes.md +48 -36
  254. package/src/skf-update-skill/references/health-check.md +5 -11
  255. package/src/skf-update-skill/references/init.md +40 -32
  256. package/src/skf-update-skill/references/manual-section-rules.md +1 -2
  257. package/src/skf-update-skill/references/merge-conflict-rules.md +1 -52
  258. package/src/skf-update-skill/references/merge.md +13 -57
  259. package/src/skf-update-skill/references/re-extract.md +27 -25
  260. package/src/skf-update-skill/references/report.md +14 -7
  261. package/src/skf-update-skill/references/validate.md +32 -30
  262. package/src/skf-update-skill/references/write.md +86 -51
  263. package/src/skf-update-skill/scripts/skf-new-file-diff.py +167 -0
  264. package/src/skf-verify-stack/SKILL.md +11 -21
  265. package/src/skf-verify-stack/customize.toml +12 -3
  266. package/src/skf-verify-stack/references/coverage-patterns.md +1 -29
  267. package/src/skf-verify-stack/references/coverage.md +21 -10
  268. package/src/skf-verify-stack/references/exit-codes.md +14 -0
  269. package/src/skf-verify-stack/references/health-check.md +1 -1
  270. package/src/skf-verify-stack/references/init.md +20 -25
  271. package/src/skf-verify-stack/references/integration-verification-rules.md +10 -19
  272. package/src/skf-verify-stack/references/integrations.md +44 -49
  273. package/src/skf-verify-stack/references/report.md +28 -34
  274. package/src/skf-verify-stack/references/requirements.md +3 -3
  275. package/src/skf-verify-stack/references/synthesize.md +36 -39
  276. package/src/skf-verify-stack/scripts/skf-coverage-tally.py +196 -0
  277. package/src/skf-verify-stack/scripts/skf-report-delta.py +256 -0
  278. package/src/skf-verify-stack/scripts/skf-verdict-rollup.py +258 -0
  279. package/tools/cli/lib/ui.js +3 -2
  280. package/docs/deepwiki.md +0 -89
  281. package/src/skf-rename-skill/references/rebuild-context.md +0 -110
@@ -0,0 +1,75 @@
1
+ ---
2
+ nextStepFile: 'step-09-refine.md'
3
+ stateSchemaFile: 'assets/campaign-state-schema.json'
4
+ stateFile: '{campaignWorkspacePath}/_campaign-state.yaml'
5
+ backupFile: '{campaignWorkspacePath}/_campaign-state.yaml.bak'
6
+ validateScript: 'scripts/campaign-validate-state.py'
7
+ ---
8
+
9
+ <!-- Config: communicate in {communication_language}. -->
10
+
11
+ # Verify
12
+
13
+ ## STEP GOAL:
14
+
15
+ Invoke VS (skf-verify-stack) in headless mode against all completed campaign skills to produce a feasibility report. The report cross-references generated skills against the project's architecture document, providing coverage analysis and integration verdicts for operator review.
16
+
17
+ ## RULES
18
+
19
+ - This step uses the **read-backup-modify-write** pattern.
20
+ - Validate state on load via `uv run {validateScript} --state-file {stateFile}`; HALT (exit 3) on non-zero.
21
+ - Update `campaign.last_updated` to current ISO-8601 with timezone on every write.
22
+ - Update `campaign.current_stage` to `7`.
23
+ - If `{headless_mode}` is true, auto-proceed through confirmation gates. VS supports headless via `--headless`.
24
+
25
+ ## TASKS
26
+
27
+ ### §1 — Read + Validate State
28
+
29
+ Load `{stateFile}`. Run `uv run {validateScript} --state-file {stateFile}`; on non-zero, HALT (exit 3) with the script's `errors[]`.
30
+
31
+ ### §2 — Read Directive
32
+
33
+ If `campaign.directive_path` is set in state, load the file at that path and apply its contents as campaign-wide context for this stage's processing, per the directive contract in `references/campaign-directive-spec.md`. If the file is not found, continue without error (directive is optional).
34
+
35
+ ### §3 — Locate Architecture Doc
36
+
37
+ Resolve the architecture document path, preferring the value persisted in state:
38
+
39
+ 1. If `campaign.architecture_doc_path` is set in state and the file exists, use it directly.
40
+ 2. Otherwise discover it: check `docs/architecture.md` at `{project-root}` (SKF convention), then `_bmad-output/planning-artifacts/architecture.md` (BMM convention).
41
+ 3. If still not found and `{headless_mode}` is false: prompt the operator to provide the architecture doc path.
42
+ 4. If still not found and `{headless_mode}` is true: skip VS invocation with a warning — do not HALT. Log that verification was skipped due to missing architecture doc (to the decision log) and proceed to §6.
43
+
44
+ Once resolved (steps 2–3), persist the path to `campaign.architecture_doc_path` so the refine stage and any resume reuse it without re-prompting. Then proceed to §4 with the resolved path.
45
+
46
+ ### §4 — Invoke VS
47
+
48
+ Invoke `skf-verify-stack` with `--headless --architecture-doc <path>`, where `<path>` is the architecture doc discovered in §3.
49
+
50
+ VS discovers skills from its own configured `{skills_output_folder}` — the campaign does NOT pass individual skill paths. Capture the result envelope from stdout:
51
+
52
+ ```
53
+ SKF_VERIFY_STACK_RESULT_JSON: {"status":"…","report_path":"…","report_latest_path":"…","overall_verdict":"…","coverage_percentage":0,"recommendation_count":0,"exit_code":0,"halt_reason":null}
54
+ ```
55
+
56
+ ### §5 — Handle VS Outcome
57
+
58
+ **On success** (exit code 0): persist the summary to `campaign.verification` (detailed findings stay in the external report):
59
+
60
+ - `campaign.verification.report_path` — `report_latest_path` from the envelope
61
+ - `campaign.verification.overall_verdict` — one of `Verified`, `Plausible`, `Risky`, `Blocked`
62
+ - `campaign.verification.coverage_percentage` — from the envelope
63
+ - `campaign.verification.recommendation_count` — from the envelope
64
+
65
+ Also set `campaign.capstone.verified` to `true` when `overall_verdict == "Verified"`, otherwise `false` (only if a `campaign.capstone` entry exists from step-07).
66
+
67
+ **On VS failure** (non-zero exit): log the error (exit code and halt_reason from the envelope or stderr). Verification failure does NOT block the campaign — it produces diagnostic information for operator review. Leave `campaign.verification` unset (or null). Continue to §6 regardless of outcome.
68
+
69
+ ### §6 — Stage Completion
70
+
71
+ Set `campaign.current_stage` to `7`. Update `campaign.last_updated` to current ISO-8601 with timezone. Backup `{stateFile}` to `{backupFile}`, then write the updated state (including `campaign.architecture_doc_path` from §3 and `campaign.verification` from §5).
72
+
73
+ ## OUTPUT
74
+
75
+ Display verification summary: overall verdict (or "skipped" if architecture doc was not found), report path (if produced), and coverage percentage. Chain to `{nextStepFile}`.
@@ -0,0 +1,83 @@
1
+ ---
2
+ nextStepFile: 'step-10-export.md'
3
+ stateSchemaFile: 'assets/campaign-state-schema.json'
4
+ stateFile: '{campaignWorkspacePath}/_campaign-state.yaml'
5
+ backupFile: '{campaignWorkspacePath}/_campaign-state.yaml.bak'
6
+ validateScript: 'scripts/campaign-validate-state.py'
7
+ ---
8
+
9
+ <!-- Config: communicate in {communication_language}. -->
10
+
11
+ # Refine
12
+
13
+ ## STEP GOAL:
14
+
15
+ Invoke RA (skf-refine-architecture) in headless mode with the project's architecture document and VS feasibility report to produce a refined architecture. RA identifies gaps, issues, and improvements based on the generated skills and applies them to the architecture document.
16
+
17
+ ## RULES
18
+
19
+ - This step uses the **read-backup-modify-write** pattern.
20
+ - Validate state on load via `uv run {validateScript} --state-file {stateFile}`; HALT (exit 3) on non-zero.
21
+ - Update `campaign.last_updated` to current ISO-8601 with timezone on every write.
22
+ - Update `campaign.current_stage` to `8`.
23
+ - If `{headless_mode}` is true, auto-proceed through confirmation gates. RA supports headless via `--headless`.
24
+
25
+ ## TASKS
26
+
27
+ ### §1 — Read + Validate State
28
+
29
+ Load `{stateFile}`. Run `uv run {validateScript} --state-file {stateFile}`; on non-zero, HALT (exit 3) with the script's `errors[]`.
30
+
31
+ ### §2 — Read Directive
32
+
33
+ If `campaign.directive_path` is set in state, load the file at that path and apply its contents as campaign-wide context for this stage's processing, per the directive contract in `references/campaign-directive-spec.md`. If the file is not found, continue without error (directive is optional).
34
+
35
+ ### §3 — Locate Inputs
36
+
37
+ **Architecture doc:** Use the same resolution strategy as step-08:
38
+
39
+ 1. If `campaign.architecture_doc_path` is set in state and the file exists, use it directly (step-08 normally persists it).
40
+ 2. Otherwise check `docs/architecture.md` at `{project-root}`, then `_bmad-output/planning-artifacts/architecture.md`.
41
+ 3. If still not found and `{headless_mode}` is false: prompt the operator.
42
+ 4. If still not found and `{headless_mode}` is true: skip RA invocation with a warning — do not HALT. Log that refinement was skipped due to missing architecture doc (to the decision log) and proceed to §6.
43
+
44
+ Once resolved (steps 2–3), persist the path to `campaign.architecture_doc_path` if not already set, then proceed to §4 with the resolved path.
45
+
46
+ **VS feasibility report:** If chaining from step-08, the report path is available from the VS result envelope (`report_latest_path`). On resume, look for `feasibility-report-*-latest.md` in `{forge_data_folder}/`. If no report exists (VS may have failed or been skipped in step-08), proceed without it — RA's VS report input is optional.
47
+
48
+ ### §4 — Invoke RA
49
+
50
+ Invoke `skf-refine-architecture` with:
51
+
52
+ ```
53
+ skf-refine-architecture --headless --architecture-doc <arch_path> [--vs-report-path <report_path>] [--scope-skills <names>]
54
+ ```
55
+
56
+ - `--architecture-doc`: the architecture doc discovered in §3 (required).
57
+ - `--vs-report-path`: the VS feasibility report path from §3 (omit if not found).
58
+ - `--scope-skills`: comma-separated names of completed campaign skills (from `skills[]` where `status == "completed"`). Optional but improves focus by limiting refinement scope to campaign-relevant skills.
59
+
60
+ Capture the result envelope from stdout:
61
+
62
+ ```
63
+ SKF_REFINE_ARCHITECTURE_RESULT_JSON: {"status":"…","refined_path":"…","gap_count":0,"issue_count":0,"improvement_count":0,"exit_code":0,"halt_reason":null}
64
+ ```
65
+
66
+ ### §5 — Handle RA Outcome
67
+
68
+ **On success** (exit code 0): persist the summary to `campaign.refinement` (the refined document itself lives at `refined_path`):
69
+
70
+ - `campaign.refinement.refined_path` — from the envelope
71
+ - `campaign.refinement.gap_count` — from the envelope
72
+ - `campaign.refinement.issue_count` — from the envelope
73
+ - `campaign.refinement.improvement_count` — from the envelope
74
+
75
+ **On RA failure** (non-zero exit): log the error (exit code and halt_reason from the envelope or stderr). Refinement failure does NOT block the campaign — the campaign continues to export with whatever state exists. Leave `campaign.refinement` unset (or null). Continue to §6 regardless of outcome.
76
+
77
+ ### §6 — Stage Completion
78
+
79
+ Set `campaign.current_stage` to `8`. Update `campaign.last_updated` to current ISO-8601 with timezone. Backup `{stateFile}` to `{backupFile}`, then write the updated state (including `campaign.refinement` from §5).
80
+
81
+ ## OUTPUT
82
+
83
+ Display refinement summary: refined architecture path (or "skipped" if architecture doc was not found), gap count, issue count, and improvement count. Chain to `{nextStepFile}`.
@@ -0,0 +1,106 @@
1
+ ---
2
+ nextStepFile: 'step-11-maintenance.md'
3
+ stateSchemaFile: 'assets/campaign-state-schema.json'
4
+ stateFile: '{campaignWorkspacePath}/_campaign-state.yaml'
5
+ backupFile: '{campaignWorkspacePath}/_campaign-state.yaml.bak'
6
+ validateScript: 'scripts/campaign-validate-state.py'
7
+ ---
8
+
9
+ <!-- Config: communicate in {communication_language}. -->
10
+
11
+ # Export
12
+
13
+ ## STEP GOAL:
14
+
15
+ Present all completed skills for operator review and gate the export behind explicit confirmation. This is the only campaign step that requires manual approval before proceeding — no files are written until the operator confirms.
16
+
17
+ ## RULES
18
+
19
+ - This step uses the **read-backup-modify-write** pattern.
20
+ - Validate state on load via `uv run {validateScript} --state-file {stateFile}`; HALT (exit 3) on non-zero.
21
+ - Update `campaign.last_updated` to current ISO-8601 with timezone on every write.
22
+ - Update `campaign.current_stage` to `9`.
23
+ - If `{headless_mode}` is true, auto-proceed past the write-gate with `[E]` and log: "headless: auto-proceed past export write-gate".
24
+
25
+ ## TASKS
26
+
27
+ ### §1 — Read + Validate State
28
+
29
+ Load `{stateFile}`. Run `uv run {validateScript} --state-file {stateFile}`; on non-zero, HALT (exit 3) with the script's `errors[]`.
30
+
31
+ ### §2 — Read Directive
32
+
33
+ If `campaign.directive_path` is set in state, load the file at that path and apply its contents as campaign-wide context for this stage's processing, per the directive contract in `references/campaign-directive-spec.md`. If the file is not found, continue without error (directive is optional).
34
+
35
+ ### §3 — Collect Export Candidates
36
+
37
+ Gather all skills from `skills[]` with `status == "completed"`. These are the export candidates.
38
+
39
+ If no completed skills exist, display a warning and proceed directly to §6 (stage completion) — there is nothing to export.
40
+
41
+ Present a summary table of export candidates:
42
+
43
+ | # | Name | Tier | Quality Score | Skill Path |
44
+ |---|------|------|---------------|------------|
45
+ | 1 | {name} | {tier} | {quality_score} | {skill_path} |
46
+ | ... | ... | ... | ... | ... |
47
+
48
+ Display: "**{N} skill(s) ready for export.**"
49
+
50
+ ### §4 — Write-Gate HALT
51
+
52
+ Present the export confirmation gate:
53
+
54
+ "**Export Gate — Confirm before writing files**
55
+
56
+ {N} completed skill(s) will be exported via `skf-export-skill`:
57
+
58
+ {summary table from §3}
59
+
60
+ - **[E]xport all** — invoke `skf-export-skill` for each completed skill
61
+ - **[C]ancel** — halt the campaign gracefully (no files written, resume later)
62
+
63
+ Choose [E] or [C]:"
64
+
65
+ **HALT and wait for operator input.**
66
+
67
+ **Headless mode:** auto-proceed with `[E]` and log: "headless: auto-proceed past export write-gate".
68
+
69
+ #### On `[C]ancel`:
70
+
71
+ Display: "Export cancelled by operator. Campaign halted gracefully — no files written. Resume later to retry export."
72
+
73
+ Log the cancellation to the decision log, then HALT with exit code 11 (`export-cancelled`). Do NOT mark the campaign as failed — this is a graceful, resumable halt; the operator may resume later.
74
+
75
+ #### On `[E]xport`:
76
+
77
+ Log the export decision to the decision log, then proceed to §5.
78
+
79
+ ### §5 — Invoke EX
80
+
81
+ For each completed skill (from §3), invoke `skf-export-skill` in headless mode:
82
+
83
+ ```
84
+ skf-export-skill {skill_name} --headless
85
+ ```
86
+
87
+ Capture the result envelope `SKF_EXPORT_RESULT_JSON` per skill.
88
+
89
+ **On per-skill EX success** (exit code 0): log the result and continue.
90
+
91
+ **On per-skill EX failure** (non-zero exit): log the error (exit code, envelope if available, or stderr). Continue with remaining skills — per-skill failure does not block remaining exports.
92
+
93
+ After all exports complete, display a summary:
94
+
95
+ "**Export Results:**
96
+ - Exported: {success_count} skill(s)
97
+ - Failed: {fail_count} skill(s)
98
+ {list of failed skills if any}"
99
+
100
+ ### §6 — Stage Completion
101
+
102
+ Set `campaign.current_stage` to `9`. Update `campaign.last_updated` to current ISO-8601 with timezone. Backup `{stateFile}` to `{backupFile}`, then write the updated state.
103
+
104
+ ## OUTPUT
105
+
106
+ Display export summary: skills exported count, failures count (if any), and per-skill results. Chain to `{nextStepFile}`.
@@ -0,0 +1,84 @@
1
+ ---
2
+ nextStepFile: 'health-check.md'
3
+ stateSchemaFile: 'assets/campaign-state-schema.json'
4
+ stateFile: '{campaignWorkspacePath}/_campaign-state.yaml'
5
+ backupFile: '{campaignWorkspacePath}/_campaign-state.yaml.bak'
6
+ reportFile: '{campaignWorkspacePath}/campaign-report.md'
7
+ reportScript: 'scripts/campaign-report.py'
8
+ reportTemplate: '{reportTemplatePath}'
9
+ validateScript: 'scripts/campaign-validate-state.py'
10
+ ---
11
+
12
+ <!-- Config: communicate in {communication_language}. -->
13
+
14
+ # Maintenance
15
+
16
+ ## STEP GOAL:
17
+
18
+ Generate a comprehensive campaign report from the accumulated state, emit the headless result envelope, and chain to the shared health check as the campaign's terminal step.
19
+
20
+ ## RULES
21
+
22
+ - This step uses the **read-backup-modify-write** pattern.
23
+ - Validate state on load via `uv run {validateScript} --state-file {stateFile}`; HALT (exit 3) on non-zero.
24
+ - Update `campaign.last_updated` to current ISO-8601 with timezone on every write.
25
+ - Update `campaign.current_stage` to `10`.
26
+ - If `{headless_mode}` is true, auto-proceed through confirmation gates. Emit the headless envelope on stdout.
27
+
28
+ ## TASKS
29
+
30
+ ### §1 — Read + Validate State
31
+
32
+ Load `{stateFile}`. Run `uv run {validateScript} --state-file {stateFile}`; on non-zero, HALT (exit 3) with the script's `errors[]`.
33
+
34
+ ### §2 — Generate Campaign Report
35
+
36
+ Invoke the campaign report script:
37
+
38
+ ```
39
+ uv run {reportScript} \
40
+ --state-file {stateFile} \
41
+ --template-file {reportTemplate} \
42
+ --output-file {reportFile}
43
+ ```
44
+
45
+ Capture the JSON result from stdout — it carries `skills_completed`, `skills_failed`, `quality_scores`, and `duration` already computed. Do not recompute these by hand in §3.
46
+
47
+ **On success** (exit code 0): log the report path and summary stats from the result JSON.
48
+
49
+ **On failure** (exit code 2): the campaign itself has already completed — do NOT discard it over a missing summary artifact. Display the error from stderr, log "report generation failed (degraded): {error}" to the decision log, set the envelope's `campaign_report_path` to `null`, and CONTINUE to §3. Surface `report-failure` only as a degraded signal in the envelope (`status:"error"`, `exit_code:10`), never as a hard halt that throws away a finished campaign.
50
+
51
+ Display: "**Campaign report generated:** `{reportFile}`" (or, on degrade, "**Campaign complete — report generation failed (see decision log); state is intact.**")
52
+
53
+ **Optional post-completion hook:** if `{onComplete}` (resolved in On Activation) is non-empty, invoke `{onComplete} --report-path={reportFile}`. Log the outcome to the decision log; a hook failure is recorded but never fails the campaign.
54
+
55
+ ### §3 — Emit Headless Envelope
56
+
57
+ When `{headless_mode}` is true, emit the campaign result envelope on stdout, copying the counts, `quality_scores`, and `duration` straight from the §2 report-script result (do not recompute):
58
+
59
+ ```
60
+ SKF_CAMPAIGN_RESULT_JSON: {"status":"success","skills_completed":N,"skills_failed":N,"quality_scores":{...},"campaign_report_path":"{reportFile}","decision_log":"{campaignWorkspacePath}/_campaign-decision-log.md","duration":"..."}
61
+ ```
62
+
63
+ - `status`: "success" if the campaign completed normally (HARD HALTs emit the error variant per the "Result Contract on HARD HALT" in `references/campaign-contracts.md`)
64
+ - `skills_completed` / `skills_failed` / `quality_scores` / `duration`: from the §2 report-script result JSON
65
+ - `campaign_report_path`: `{reportFile}`
66
+ - `decision_log`: path to the append-only decision log
67
+
68
+ When not in headless mode, skip this section silently.
69
+
70
+ ### §4 — Stage Completion
71
+
72
+ Set `campaign.current_stage` to `10`. Update `campaign.last_updated` to current ISO-8601 with timezone. Backup `{stateFile}` to `{backupFile}`, then write the updated state.
73
+
74
+ ### §5 — Chain to Health Check
75
+
76
+ The operator's findings-routing consent (`campaign.health_findings_queue`) is applied by the terminal health-check step: `references/health-check.md` §1 reads it from state and carries it into the shared health check as the pre-decided opt-in (`"improvement"` → route non-bug findings to the shared improvement queue without re-prompting; `"local"` → local queue only). Surface the active setting here.
77
+
78
+ Display: "**Campaign complete.** Report at `{reportFile}`. Findings routing: {campaign.health_findings_queue}. Chaining to health check..."
79
+
80
+ Chain to `{nextStepFile}` (shared/health-check.md).
81
+
82
+ ## OUTPUT
83
+
84
+ Display campaign completion summary: skills completed, skills failed, report path, total duration. Chain to `{nextStepFile}`.
@@ -0,0 +1,115 @@
1
+ ---
2
+ stateSchemaFile: 'assets/campaign-state-schema.json'
3
+ stateFile: '{campaignWorkspacePath}/_campaign-state.yaml'
4
+ backupFile: '{campaignWorkspacePath}/_campaign-state.yaml.bak'
5
+ validateScript: 'scripts/campaign-validate-state.py'
6
+ statusScript: 'scripts/campaign-status.py'
7
+ ---
8
+
9
+ <!-- Config: communicate in {communication_language}. -->
10
+
11
+ # Resume
12
+
13
+ ## STEP GOAL:
14
+
15
+ Validate campaign state integrity, determine the resume point, and chain to the appropriate stage step file. This is a read-only routing step — it does not modify state.
16
+
17
+ ## RULES
18
+
19
+ - This step is **read-only by default** — it does NOT modify `{stateFile}` except in the one recovery case below (restoring a valid `.bak` over a corrupt primary), which is the State Contract's advertised safety net.
20
+ - Validate state on load via `uv run {validateScript} --state-file {stateFile}`; the recovery path in §1 governs what happens on failure.
21
+ - The chain target is determined dynamically from state — there is no fixed `nextStepFile`.
22
+ - If `{headless_mode}` is true, auto-proceed through any confirmation gates with the default action and log each auto-decision.
23
+
24
+ ## TASKS
25
+
26
+ ### §1 — Read + Validate State (with `.bak` recovery)
27
+
28
+ Load `{stateFile}`. If the file does not exist, HALT (exit code 2, `invalid-input`): "No campaign state found. Run `campaign` to start a new campaign."
29
+
30
+ Run `uv run {validateScript} --state-file {stateFile}`. If it succeeds (exit 0), proceed to §2.
31
+
32
+ If it fails (primary missing/corrupt YAML/schema-invalid), **attempt automatic recovery from the backup** rather than dead-halting — this is exactly the crash-during-write case the State Contract promises `.bak` covers:
33
+
34
+ 1. If `{backupFile}` exists, run `uv run {validateScript} --state-file {backupFile}`.
35
+ 2. If the backup is valid: copy `{backupFile}` over `{stateFile}`, log to the decision log "primary corrupt — recovered from backup as of {bak.last_updated}", inform the operator, and continue with the recovered state.
36
+ 3. If the backup is missing or also invalid: HALT with exit code 9 (`corrupt-state`), reporting both the primary and backup validation errors so the operator knows neither is usable.
37
+
38
+ ### §2 — Backup Consistency Check
39
+
40
+ Check if `{backupFile}` exists.
41
+
42
+ **If `.bak` does not exist:** warn "No backup file found — campaign may have been created but never modified." Continue.
43
+
44
+ **If `.bak` exists** (and §1 did not already recover from it):
45
+
46
+ 1. Run `uv run {validateScript} --state-file {backupFile}`. If invalid, warn: "Backup file fails validation — cannot use for recovery." Continue with the primary.
47
+ 2. Compare primary vs backup deterministically: run `uv run {statusScript} --state-file {stateFile} --backup-file {backupFile}` and read `backup_comparison.primary_behind` (the script does the ISO-8601 timestamp and `current_stage` compares — do not order the timestamps by hand). If it is `true`, the primary looks behind the backup (possible crash during last write). Present a recovery choice:
48
+ - `[R]ecover` — copy `{backupFile}` over `{stateFile}` and resume from the backup's state.
49
+ - `[K]eep` — keep the primary as authoritative (the default).
50
+
51
+ In headless mode, default to `[K]eep` and log the auto-decision (a behind-backup primary may be intentional; never silently overwrite without a clear corruption signal — that case is handled in §1). Otherwise the primary is authoritative.
52
+
53
+ ### §3 — Determine Resume Point
54
+
55
+ Two paths based on whether `--from=<skill>` was provided in the invocation:
56
+
57
+ **With `--from=<skill>`:**
58
+
59
+ 1. Find the named skill in `skills[]` by `name`.
60
+ 2. If not found → HALT (exit code 2, `invalid-input`): "Unknown skill '{name}'. Known skills: {comma-separated list of all skill names from state}."
61
+ 3. If the skill's `status` is `"completed"`, `"failed"`, or `"skipped"`, the operator may have meant to re-run it (e.g. it passed with a low score) rather than skip past it. Present a choice:
62
+ - `[R]e-run` — reset the named skill to `"pending"` and resume from its stage. (Read-only step caveat: this single status reset follows read-backup-modify-write — back up first.)
63
+ - `[N]ext` — find the next skill in `dependency_graph.execution_order` after the named one whose `status` is `"pending"` or `"active"` and resume there. If none found → HALT (exit code 0, campaign already complete): "All remaining skills are complete. Run `campaign` to start a new campaign."
64
+ - `[H]alt` — stop without resuming.
65
+
66
+ In headless mode, default to `[N]ext` and log the auto-decision. Log the chosen action to the decision log.
67
+ 4. If an active skill already exists in `skills[]` AND it is a different skill from the `--from` target, warn: "Skill '{active_name}' is currently active — honoring explicit --from override."
68
+ 5. Determine the target step file:
69
+ - Tier A skill with status `"pending"` or `"active"` → stage 4 (`step-05-skill-loop.md`)
70
+ - Tier B skill with status `"pending"` or `"active"` → stage 5 (`step-06-batch.md`)
71
+
72
+ **Without `--from`:**
73
+
74
+ 1. Scan `skills[]` for any skill with `status == "active"`.
75
+ - If found and `tier == "A"` → resume target is stage 4 (`step-05-skill-loop.md`). The skill loop's §4 will skip completed skills until it reaches the active one.
76
+ - If found and `tier == "B"` → resume target is stage 5 (`step-06-batch.md`). The batch step processes Tier B skills.
77
+ 2. If no active skill → the next stage to run is `campaign.current_stage + 1`, because `current_stage` records the highest **completed** stage (each stage writes its own number only after its work and gates finish, so a mid-stage halt leaves the previous stage's number on disk). **Terminal cap:** if `campaign.current_stage` is `10`, the resolved stage is `10` itself (`step-11-maintenance.md`) — never `11`; the existing terminal-HALT check in §4 governs whether a stage-10 campaign is already done.
78
+ 3. Map the resolved stage number to the corresponding step file using the stage table in §4.
79
+
80
+ ### §4 — Resume Routing
81
+
82
+ Map the resolved stage number to its step file. Both §3 branches feed this table an **already-resolved** stage number: the active-skill branch supplies stage 4 or 5 directly (and BYPASSES the `+1`), while the no-active-skill branch supplies `current_stage + 1` (terminal-capped at 10). Do not apply the `+1` again here.
83
+
84
+ | Stage | Step File |
85
+ |-------|-----------|
86
+ | 0 | step-01-setup.md |
87
+ | 1 | step-02-strategy.md |
88
+ | 2 | step-03-pins.md |
89
+ | 3 | step-04-provenance.md |
90
+ | 4 | step-05-skill-loop.md |
91
+ | 5 | step-06-batch.md |
92
+ | 6 | step-07-capstone.md |
93
+ | 7 | step-08-verify.md |
94
+ | 8 | step-09-refine.md |
95
+ | 9 | step-10-export.md |
96
+ | 10 | step-11-maintenance.md |
97
+
98
+ Derive the skill counts deterministically — `uv run {statusScript} --state-file {stateFile}` returns `completed`, `total`, and the per-status counts (`pending` / `active` / `failed` / `skipped`); do not hand-count `skills[]`. Display a resume summary before chaining:
99
+
100
+ ```
101
+ CAMPAIGN RESUME: {campaign.name}
102
+
103
+ Resuming from: Stage {stage_number} — {stage_name}
104
+ Target skill: {skill_name} (if --from was used, otherwise "auto-detected" or "N/A")
105
+ Skills completed: {completed} / {total}
106
+ Skills remaining: {pending} pending, {active} active, {failed} failed, {skipped} skipped
107
+ Last updated: {campaign.last_updated}
108
+ ```
109
+
110
+ If `campaign.current_stage` is `10` and all skills have status `"completed"`, `"failed"`, or `"skipped"`:
111
+ HALT (exit code 0, campaign already complete): "Campaign has reached its final stage. All skills have been processed."
112
+
113
+ ## OUTPUT
114
+
115
+ Chain to the determined step file.
File without changes