bmad-module-skill-forge 1.4.0 → 1.5.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 (231) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/README.md +0 -8
  3. package/docs/_data/pinned.yaml +1 -1
  4. package/docs/_internal/STABILITY.md +1 -1
  5. package/docs/architecture.md +2 -2
  6. package/docs/examples.md +1 -1
  7. package/docs/workflows.md +5 -5
  8. package/package.json +2 -2
  9. package/src/README.md +1 -1
  10. package/src/knowledge/ccc-bridge.md +12 -12
  11. package/src/knowledge/qmd-registry.md +5 -5
  12. package/src/shared/health-check.md +5 -5
  13. package/src/shared/references/description-guard-protocol.md +100 -0
  14. package/src/shared/references/output-contract-schema.md +1 -1
  15. package/src/shared/scripts/schemas/skf-brief-result-envelope.v1.json +6 -6
  16. package/src/shared/scripts/schemas/skf-setup-result-envelope.v1.json +9 -3
  17. package/src/shared/scripts/schemas/skf-update-result-envelope.v1.json +149 -0
  18. package/src/shared/scripts/schemas/skill-brief.v1.json +22 -2
  19. package/src/shared/scripts/skf-build-change-manifest.py +420 -0
  20. package/src/shared/scripts/skf-check-workspace-drift.py +321 -0
  21. package/src/shared/scripts/skf-compare-file-hashes.py +357 -0
  22. package/src/shared/scripts/skf-description-guard.py +359 -0
  23. package/src/shared/scripts/skf-detect-language.py +2 -2
  24. package/src/shared/scripts/skf-detect-scripts-assets.py +613 -0
  25. package/src/shared/scripts/skf-detect-tools.py +97 -8
  26. package/src/shared/scripts/skf-detect-workspaces.py +1 -1
  27. package/src/shared/scripts/skf-disqualify-candidates.py +576 -0
  28. package/src/shared/scripts/skf-emit-brief-result-envelope.py +3 -3
  29. package/src/shared/scripts/skf-emit-result-envelope.py +93 -9
  30. package/src/shared/scripts/skf-enumerate-stack-skills.py +514 -0
  31. package/src/shared/scripts/skf-forge-tier-rw.py +11 -11
  32. package/src/shared/scripts/skf-hash-content.py +284 -0
  33. package/src/shared/scripts/skf-load-provenance.py +295 -0
  34. package/src/shared/scripts/skf-merge-ccc-exclusions.py +45 -1
  35. package/src/shared/scripts/skf-pair-intersect.py +250 -0
  36. package/src/shared/scripts/skf-provenance-gap-dispatch.py +433 -0
  37. package/src/shared/scripts/skf-qmd-classify-collections.py +42 -8
  38. package/src/shared/scripts/skf-recommend-scope-type.py +2 -2
  39. package/src/shared/scripts/skf-render-quick-metadata.py +2 -2
  40. package/src/shared/scripts/skf-resolve-authoritative-files.py +504 -0
  41. package/src/shared/scripts/skf-scan-manifests.py +738 -0
  42. package/src/shared/scripts/skf-scan-skill-md-structure.py +375 -0
  43. package/src/shared/scripts/skf-update-active-symlink.py +315 -0
  44. package/src/shared/scripts/skf-validate-brief-inputs.py +5 -5
  45. package/src/shared/scripts/skf-validate-brief-schema.py +348 -0
  46. package/src/shared/scripts/skf-write-skill-brief.py +61 -5
  47. package/src/skf-analyze-source/SKILL.md +69 -16
  48. package/src/skf-analyze-source/assets/skill-brief-schema.md +1 -1
  49. package/src/skf-analyze-source/customize.toml +55 -0
  50. package/src/skf-analyze-source/{steps-c/step-01b-continue.md → references/continue.md} +12 -12
  51. package/src/skf-analyze-source/{steps-c/step-06-generate-briefs.md → references/generate-briefs.md} +29 -10
  52. package/src/skf-analyze-source/{steps-c/step-07-health-check.md → references/health-check.md} +5 -3
  53. package/src/skf-analyze-source/{steps-c/step-03-identify-units.md → references/identify-units.md} +44 -14
  54. package/src/skf-analyze-source/{steps-c/step-01-init.md → references/init.md} +27 -6
  55. package/src/skf-analyze-source/{steps-c/step-04-map-and-detect.md → references/map-and-detect.md} +52 -25
  56. package/src/skf-analyze-source/{steps-c/step-05-recommend.md → references/recommend.md} +15 -8
  57. package/src/skf-analyze-source/{steps-c/step-02-scan-project.md → references/scan-project.md} +12 -10
  58. package/src/skf-analyze-source/references/unit-detection-heuristics.md +2 -0
  59. package/src/skf-analyze-source/templates/analysis-report-template.md +6 -6
  60. package/src/skf-audit-skill/SKILL.md +66 -15
  61. package/src/skf-audit-skill/assets/drift-report-template.md +6 -5
  62. package/src/skf-audit-skill/customize.toml +49 -0
  63. package/src/skf-audit-skill/{steps-c/step-07-health-check.md → references/health-check.md} +5 -3
  64. package/src/skf-audit-skill/references/init.md +305 -0
  65. package/src/skf-audit-skill/{steps-c/step-02-re-index.md → references/re-index.md} +11 -11
  66. package/src/skf-audit-skill/{steps-c/step-06-report.md → references/report.md} +25 -7
  67. package/src/skf-audit-skill/{steps-c/step-04-semantic-diff.md → references/semantic-diff.md} +6 -6
  68. package/src/skf-audit-skill/{steps-c/step-05-severity-classify.md → references/severity-classify.md} +5 -5
  69. package/src/skf-audit-skill/references/severity-rules.md +2 -0
  70. package/src/skf-audit-skill/{steps-c/step-03-structural-diff.md → references/structural-diff.md} +29 -16
  71. package/src/skf-brief-skill/SKILL.md +48 -18
  72. package/src/skf-brief-skill/assets/description-voice-examples.md +1 -1
  73. package/src/skf-brief-skill/assets/skill-brief-schema.md +32 -2
  74. package/src/skf-brief-skill/customize.toml +44 -0
  75. package/src/skf-brief-skill/{steps-c/step-02-analyze-target.md → references/analyze-target.md} +5 -5
  76. package/src/skf-brief-skill/{steps-c/step-04-confirm-brief.md → references/confirm-brief.md} +13 -10
  77. package/src/skf-brief-skill/references/draft-checkpoint.md +4 -4
  78. package/src/skf-brief-skill/{steps-c/step-01-gather-intent.md → references/gather-intent.md} +24 -24
  79. package/src/skf-brief-skill/references/headless-args.md +9 -9
  80. package/src/skf-brief-skill/references/headless-source-authority-detection.md +1 -1
  81. package/src/skf-brief-skill/{steps-c/step-06-health-check.md → references/health-check.md} +4 -2
  82. package/src/skf-brief-skill/references/portfolio-similarity-check.md +2 -2
  83. package/src/skf-brief-skill/references/qmd-collection-registration.md +1 -1
  84. package/src/skf-brief-skill/{steps-c/step-03-scope-definition.md → references/scope-definition.md} +19 -16
  85. package/src/skf-brief-skill/references/version-resolution.md +2 -2
  86. package/src/skf-brief-skill/{steps-c/step-05-write-brief.md → references/write-brief.md} +11 -10
  87. package/src/skf-create-skill/SKILL.md +25 -19
  88. package/src/skf-create-skill/assets/compile-assembly-rules.md +3 -3
  89. package/src/skf-create-skill/assets/skill-sections.md +5 -5
  90. package/src/skf-create-skill/assets/tessl-dismissal-rules.md +11 -11
  91. package/src/skf-create-skill/customize.toml +35 -0
  92. package/src/skf-create-skill/references/authoritative-files-protocol.md +142 -0
  93. package/src/skf-create-skill/{steps-c/step-05-compile.md → references/compile.md} +16 -16
  94. package/src/skf-create-skill/{steps-c/step-03d-component-extraction.md → references/component-extraction.md} +16 -16
  95. package/src/skf-create-skill/{steps-c/step-02-ecosystem-check.md → references/ecosystem-check.md} +4 -4
  96. package/src/skf-create-skill/{steps-c/step-04-enrich.md → references/enrich.md} +3 -3
  97. package/src/skf-create-skill/{steps-c/step-03-extract.md → references/extract.md} +52 -120
  98. package/src/skf-create-skill/references/extraction-patterns.md +8 -8
  99. package/src/skf-create-skill/{steps-c/step-07-generate-artifacts.md → references/generate-artifacts.md} +17 -9
  100. package/src/skf-create-skill/{steps-c/step-09-health-check.md → references/health-check.md} +4 -2
  101. package/src/skf-create-skill/{steps-c/step-01-load-brief.md → references/load-brief.md} +40 -32
  102. package/src/skf-create-skill/{steps-c/step-08-report.md → references/report.md} +8 -8
  103. package/src/skf-create-skill/references/source-resolution-protocols.md +6 -6
  104. package/src/skf-create-skill/{steps-c/sub/step-02b-ccc-discover.md → references/sub/ccc-discover.md} +5 -5
  105. package/src/skf-create-skill/{steps-c/sub/step-03c-fetch-docs.md → references/sub/fetch-docs.md} +28 -12
  106. package/src/skf-create-skill/{steps-c/sub/step-03b-fetch-temporal.md → references/sub/fetch-temporal.md} +81 -50
  107. package/src/skf-create-skill/{steps-c/step-06-validate.md → references/validate.md} +46 -26
  108. package/src/skf-create-stack-skill/SKILL.md +76 -17
  109. package/src/skf-create-stack-skill/assets/provenance-map-schema.md +102 -0
  110. package/src/skf-create-stack-skill/assets/stack-skill-template.md +1 -1
  111. package/src/skf-create-stack-skill/customize.toml +46 -0
  112. package/src/skf-create-stack-skill/{steps-c/step-06-compile-stack.md → references/compile-stack.md} +6 -5
  113. package/src/skf-create-stack-skill/references/compose-mode-rules.md +3 -1
  114. package/src/skf-create-stack-skill/{steps-c/step-05-detect-integrations.md → references/detect-integrations.md} +32 -11
  115. package/src/skf-create-stack-skill/{steps-c/step-02-detect-manifests.md → references/detect-manifests.md} +28 -28
  116. package/src/skf-create-stack-skill/{steps-c/step-07-generate-output.md → references/generate-output.md} +11 -85
  117. package/src/skf-create-stack-skill/{steps-c/step-10-health-check.md → references/health-check.md} +4 -2
  118. package/src/skf-create-stack-skill/{steps-c/step-01-init.md → references/init.md} +70 -4
  119. package/src/skf-create-stack-skill/references/integration-patterns.md +2 -0
  120. package/src/skf-create-stack-skill/references/manifest-patterns.md +2 -0
  121. package/src/skf-create-stack-skill/{steps-c/step-04-parallel-extract.md → references/parallel-extract.md} +40 -17
  122. package/src/skf-create-stack-skill/{steps-c/step-03-rank-and-confirm.md → references/rank-and-confirm.md} +5 -4
  123. package/src/skf-create-stack-skill/{steps-c/step-09-report.md → references/report.md} +3 -3
  124. package/src/skf-create-stack-skill/{steps-c/step-08-validate.md → references/validate.md} +6 -6
  125. package/src/skf-drop-skill/SKILL.md +84 -12
  126. package/src/skf-drop-skill/customize.toml +57 -0
  127. package/src/skf-drop-skill/{steps-c/step-02-execute.md → references/execute.md} +49 -34
  128. package/src/skf-drop-skill/{steps-c/step-04-health-check.md → references/health-check.md} +6 -4
  129. package/src/skf-drop-skill/{steps-c/step-03-report.md → references/report.md} +13 -5
  130. package/src/skf-drop-skill/{steps-c/step-01-select.md → references/select.md} +63 -15
  131. package/src/skf-export-skill/SKILL.md +85 -16
  132. package/src/skf-export-skill/assets/managed-section-format.md +3 -3
  133. package/src/skf-export-skill/assets/snippet-format.md +2 -2
  134. package/src/skf-export-skill/customize.toml +49 -0
  135. package/src/skf-export-skill/{steps-c/step-03-generate-snippet.md → references/generate-snippet.md} +18 -12
  136. package/src/skf-export-skill/{steps-c/step-07-health-check.md → references/health-check.md} +6 -4
  137. package/src/skf-export-skill/{steps-c/step-01-load-skill.md → references/load-skill.md} +21 -51
  138. package/src/skf-export-skill/references/manifest-rebuild.md +68 -0
  139. package/src/skf-export-skill/references/multi-skill-mode.md +38 -0
  140. package/src/skf-export-skill/references/orphan-context-detection.md +75 -0
  141. package/src/skf-export-skill/references/orphan-row-detection.md +102 -0
  142. package/src/skf-export-skill/{steps-c/step-02-package.md → references/package.md} +7 -7
  143. package/src/skf-export-skill/references/preflight-snippet-root-probe.md +74 -0
  144. package/src/skf-export-skill/{steps-c/step-06-summary.md → references/summary.md} +30 -6
  145. package/src/skf-export-skill/{steps-c/step-05-token-report.md → references/token-report.md} +5 -5
  146. package/src/skf-export-skill/{steps-c/step-04-update-context.md → references/update-context.md} +116 -91
  147. package/src/skf-quick-skill/SKILL.md +63 -123
  148. package/src/skf-quick-skill/customize.toml +44 -0
  149. package/src/skf-quick-skill/references/batch-mode.md +102 -0
  150. package/src/skf-quick-skill/{steps-c/step-04-compile.md → references/compile.md} +10 -10
  151. package/src/skf-quick-skill/{steps-c/step-02-ecosystem-check.md → references/ecosystem-check.md} +5 -5
  152. package/src/skf-quick-skill/{steps-c/step-06-finalize.md → references/finalize.md} +7 -7
  153. package/src/skf-quick-skill/{steps-c/step-07-health-check.md → references/health-check.md} +3 -3
  154. package/src/skf-quick-skill/{steps-c/step-03-quick-extract.md → references/quick-extract.md} +5 -5
  155. package/src/skf-quick-skill/references/registry-resolution.md +2 -0
  156. package/src/skf-quick-skill/{steps-c/step-01-resolve-target.md → references/resolve-target.md} +14 -10
  157. package/src/skf-quick-skill/{steps-c/step-05-write-and-validate.md → references/write-and-validate.md} +4 -4
  158. package/src/skf-refine-architecture/SKILL.md +86 -16
  159. package/src/skf-refine-architecture/customize.toml +49 -0
  160. package/src/skf-refine-architecture/{steps-c/step-05-compile.md → references/compile.md} +4 -4
  161. package/src/skf-refine-architecture/{steps-c/step-02-gap-analysis.md → references/gap-analysis.md} +5 -5
  162. package/src/skf-refine-architecture/{steps-c/step-07-health-check.md → references/health-check.md} +6 -4
  163. package/src/skf-refine-architecture/{steps-c/step-04-improvements.md → references/improvements.md} +5 -5
  164. package/src/skf-refine-architecture/references/init.md +144 -0
  165. package/src/skf-refine-architecture/{steps-c/step-03-issue-detection.md → references/issue-detection.md} +5 -5
  166. package/src/skf-refine-architecture/references/refinement-rules.md +2 -0
  167. package/src/skf-refine-architecture/{steps-c/step-06-report.md → references/report.md} +14 -5
  168. package/src/skf-rename-skill/SKILL.md +82 -12
  169. package/src/skf-rename-skill/customize.toml +52 -0
  170. package/src/skf-rename-skill/{steps-c/step-02-execute.md → references/execute.md} +94 -99
  171. package/src/skf-rename-skill/references/health-check.md +30 -0
  172. package/src/skf-rename-skill/references/rebuild-context.md +110 -0
  173. package/src/skf-rename-skill/{steps-c/step-03-report.md → references/report.md} +13 -5
  174. package/src/skf-rename-skill/{steps-c/step-01-select.md → references/select.md} +59 -20
  175. package/src/skf-setup/SKILL.md +35 -35
  176. package/src/skf-setup/customize.toml +33 -0
  177. package/src/skf-setup/{steps-c/step-03-auto-index.md → references/auto-index.md} +10 -18
  178. package/src/skf-setup/{steps-c/step-01b-ccc-index.md → references/ccc-index.md} +14 -22
  179. package/src/skf-setup/{steps-c/step-01-detect-and-tier.md → references/detect-and-tier.md} +23 -10
  180. package/src/skf-setup/{steps-c/step-05-health-check.md → references/health-check.md} +1 -1
  181. package/src/skf-setup/{steps-c/step-04-report.md → references/report.md} +21 -19
  182. package/src/skf-setup/references/tier-rules.md +1 -1
  183. package/src/skf-setup/{steps-c/step-02-write-config.md → references/write-config.md} +14 -13
  184. package/src/skf-test-skill/SKILL.md +77 -15
  185. package/src/skf-test-skill/customize.toml +54 -0
  186. package/src/skf-test-skill/{steps-c/step-04-coherence-check.md → references/coherence-check.md} +28 -71
  187. package/src/skf-test-skill/{steps-c/step-03-coverage-check.md → references/coverage-check.md} +16 -39
  188. package/src/skf-test-skill/{steps-c/step-02-detect-mode.md → references/detect-mode.md} +4 -26
  189. package/src/skf-test-skill/{steps-c/step-04b-external-validators.md → references/external-validators.md} +6 -28
  190. package/src/skf-test-skill/references/health-check.md +14 -0
  191. package/src/skf-test-skill/{steps-c/step-01-init.md → references/init.md} +21 -37
  192. package/src/skf-test-skill/references/migration-section-rules.md +4 -2
  193. package/src/skf-test-skill/{steps-c/step-06-report.md → references/report.md} +41 -51
  194. package/src/skf-test-skill/{steps-c/step-05-score.md → references/score.md} +26 -43
  195. package/src/skf-test-skill/references/scoring-rules.md +8 -6
  196. package/src/skf-test-skill/references/source-access-protocol.md +7 -5
  197. package/src/skf-test-skill/scripts/compute-score.py +88 -17
  198. package/src/skf-test-skill/templates/test-report-template.md +13 -13
  199. package/src/skf-update-skill/SKILL.md +23 -14
  200. package/src/skf-update-skill/customize.toml +44 -0
  201. package/src/skf-update-skill/{steps-c/step-02-detect-changes.md → references/detect-changes.md} +176 -68
  202. package/src/skf-update-skill/references/health-check.md +32 -0
  203. package/src/skf-update-skill/{steps-c/step-01-init.md → references/init.md} +56 -8
  204. package/src/skf-update-skill/references/manual-section-rules.md +4 -0
  205. package/src/skf-update-skill/references/merge-conflict-rules.md +4 -0
  206. package/src/skf-update-skill/{steps-c/step-04-merge.md → references/merge.md} +8 -8
  207. package/src/skf-update-skill/{steps-c/step-03-re-extract.md → references/re-extract.md} +53 -44
  208. package/src/skf-update-skill/references/remote-source-resolution.md +5 -1
  209. package/src/skf-update-skill/references/report.md +214 -0
  210. package/src/skf-update-skill/{steps-c/step-05-validate.md → references/validate.md} +5 -5
  211. package/src/skf-update-skill/{steps-c/step-06-write.md → references/write.md} +73 -51
  212. package/src/skf-verify-stack/SKILL.md +89 -17
  213. package/src/skf-verify-stack/assets/feasibility-report-template.md +4 -4
  214. package/src/skf-verify-stack/customize.toml +50 -0
  215. package/src/skf-verify-stack/references/coverage-patterns.md +2 -2
  216. package/src/skf-verify-stack/{steps-c/step-02-coverage.md → references/coverage.md} +7 -7
  217. package/src/skf-verify-stack/{steps-c/step-07-health-check.md → references/health-check.md} +7 -5
  218. package/src/skf-verify-stack/references/init.md +166 -0
  219. package/src/skf-verify-stack/references/integration-verification-rules.md +1 -1
  220. package/src/skf-verify-stack/{steps-c/step-03-integrations.md → references/integrations.md} +12 -12
  221. package/src/skf-verify-stack/{steps-c/step-06-report.md → references/report.md} +22 -41
  222. package/src/skf-verify-stack/{steps-c/step-04-requirements.md → references/requirements.md} +7 -7
  223. package/src/skf-verify-stack/{steps-c/step-05-synthesize.md → references/synthesize.md} +8 -8
  224. package/tools/validate-docs-drift.js +1 -1
  225. package/src/skf-audit-skill/steps-c/step-01-init.md +0 -221
  226. package/src/skf-refine-architecture/steps-c/step-01-init.md +0 -136
  227. package/src/skf-rename-skill/steps-c/step-04-health-check.md +0 -22
  228. package/src/skf-test-skill/steps-c/step-07-health-check.md +0 -25
  229. package/src/skf-update-skill/steps-c/step-07-report.md +0 -148
  230. package/src/skf-update-skill/steps-c/step-08-health-check.md +0 -22
  231. package/src/skf-verify-stack/steps-c/step-01-init.md +0 -178
@@ -0,0 +1,305 @@
1
+ ---
2
+ nextStepFile: 're-index.md'
3
+ outputFile: '{forge_version}/drift-report-{timestamp}.md'
4
+ templateFile: 'assets/drift-report-template.md'
5
+ loadProvenanceScript: '{project-root}/src/shared/scripts/skf-load-provenance.py'
6
+ compareFileHashesScript: '{project-root}/src/shared/scripts/skf-compare-file-hashes.py'
7
+ ---
8
+
9
+ <!-- Config: communicate in {communication_language}. -->
10
+
11
+ # Step 1: Initialize Audit
12
+
13
+ ## STEP GOAL:
14
+
15
+ Load the existing skill artifacts, provenance map, and forge tier configuration to establish the baseline for drift detection. Create the drift report document and present a baseline summary for user confirmation before proceeding with analysis.
16
+
17
+ ## Rules
18
+
19
+ - Focus only on loading skill artifacts and establishing the baseline — do not perform any diff or analysis
20
+ - Do not proceed if skill path is invalid or SKILL.md not found
21
+ - Present baseline summary clearly so user can confirm before analysis begins
22
+ - Docs-only limitation: If `metadata.json` indicates `source_type: "docs-only"` or `confidence_tier: "Quick"` with all T3 citations, inform user: "**This is a docs-only skill.** Drift detection compares against upstream documentation, not source code. Re-run `@Ferris US` to re-fetch documentation URLs and detect content changes." Recommend update-skill instead.
23
+
24
+ ## MANDATORY SEQUENCE
25
+
26
+ **Initialize workflow context defaults.** Before entering §1, set `confidence_mode = "normal"` as the default. §4 may upgrade this to `"degraded — all findings T1-low"` if the operator opts into degraded mode. Downstream steps (report.md, drift-report-template.md) consume this variable directly — no conditional at the usage site.
27
+
28
+ ### 1. Get Skill Path
29
+
30
+ "**Audit Skill — Drift Detection**
31
+
32
+ Which skill would you like to audit? Please provide the skill name or path."
33
+
34
+ **If user provides skill name (not full path) — version-aware path resolution (see `knowledge/version-paths.md`):**
35
+ 1. Read `{skills_output_folder}/.export-manifest.json` and look up the skill name in `exports` to get `active_version`
36
+ 2. If found: tentatively resolve `{skill_package}` = `{skills_output_folder}/{skill_name}/{active_version}/{skill_name}/`. **Manifest-vs-symlink drift gate:** before committing, also read the `active` symlink at `{skills_output_folder}/{skill_name}/active`. When the symlink target disagrees with `active_version`, the manifest lags behind on-disk state — typical sequence is `update-skill` flipped the symlink but `export-skill` has not yet rewritten the manifest. Auditing the older manifest version would re-audit a skill the user no longer cares about (or has already audited). Decide which version to audit:
37
+ - Read `forge_data_folder/{skill_name}/{active_version}/provenance-map.json` (manifest version) and `forge_data_folder/{skill_name}/{symlink_target}/provenance-map.json` (symlink target). Compare their `generated_at` timestamps (or `mtime` if the field is absent).
38
+ - If both versions exist and the symlink target's provenance is **fresher** than the manifest's `last_exported`, present a gate:
39
+
40
+ "**Manifest lags behind active symlink.**
41
+
42
+ | | Manifest | Symlink |
43
+ |---|---|---|
44
+ | Version | `{active_version}` | `{symlink_target}` |
45
+ | Exported / forged | `{manifest.last_exported}` | `{symlink_provenance_generated_at}` |
46
+
47
+ The manifest's `active_version` was set by an earlier export-skill run; the symlink was flipped later (typically by update-skill). Auditing the manifest version will re-audit a skill the user no longer treats as active. Options:
48
+
49
+ - **[N] Audit symlink target ({symlink_target})** — recommended. The drift report describes the version the skill currently resolves to.
50
+ - **[M] Audit manifest version ({active_version})** — only useful when investigating the older version specifically.
51
+ - **[X] Abort** — halt without producing a report. Run `[EX] Export Skill` to reconcile the manifest before re-running audit-skill."
52
+
53
+ Default is **[N]**. Headless mode auto-selects **[N]** with a loud log line: `"headless: manifest active_version ({active_version}) is older than symlink target ({symlink_target}); auditing symlink target. Run export-skill to reconcile."` This mirrors §5b's upstream-drift handling — when the manifest and the working tree disagree, the working tree is the more honest signal under automation.
54
+
55
+ - When the symlink target's provenance is **older** than (or equal to) the manifest's `last_exported`, the symlink predates the export — this is the normal post-export shape, no gate needed. Resolve to the manifest's `active_version`.
56
+ - When only one of the two versions has a provenance map, resolve to the version that has one (the other is inert — auditing it would degrade to text-diff). Log the choice.
57
+
58
+ 3. If not in manifest: check for `active` symlink at `{skills_output_folder}/{skill_name}/active` — resolve to `{skill_group}/active/{skill_name}/`
59
+ 4. If neither: fall back to flat path `{skills_output_folder}/{skill_name}/`. If SKILL.md exists at the flat path, auto-migrate per `knowledge/version-paths.md` migration rules
60
+ 5. Store the resolved path as `{resolved_skill_package}`. Also store `audit_target_version` = the version that was actually selected (manifest, symlink, or flat) for step 6 Provenance to surface. When the gate above fired, also record the rejected version under `manifest_symlink_drift = {manifest: {active_version}, symlink: {symlink_target}, audited: {audit_target_version}, reason: {fresher-provenance|operator-choice|headless-default}}` so reviewers can audit the choice.
61
+
62
+ **If user provides full path:**
63
+ - Use as provided
64
+
65
+ **Validate:** Check that `SKILL.md` exists at the resolved path.
66
+ - If missing → "Skill not found at `{resolved_skill_package}`. Check the path and try again."
67
+ - If found → Continue
68
+
69
+ ### 2. Load Forge Tier
70
+
71
+ Load `{sidecar_path}/forge-tier.yaml` to detect available tools.
72
+
73
+ **If file missing:**
74
+ - "Setup-forge has not been run. Cannot determine tool availability. Run `[SF] Setup Forge` first."
75
+ - HALT workflow
76
+
77
+ **If found:**
78
+ - Extract tier level: Quick / Forge / Forge+ / Deep
79
+ - Extract available tools: gh_bridge, ast_bridge, qmd_bridge — see `knowledge/tool-resolution.md` for concrete tool resolution per IDE
80
+
81
+ **Apply tier override:** Read `{sidecar_path}/preferences.yaml`. If `tier_override` is set and is a valid tier value (Quick, Forge, Forge+, or Deep), use it instead of the detected tier.
82
+
83
+ ### 3. Load Skill Artifacts
84
+
85
+ Load the following from the skill directory:
86
+
87
+ **Required:**
88
+ - `SKILL.md` — The skill document to audit
89
+ - `metadata.json` — Skill metadata (version, created date, export count)
90
+
91
+ **Extract from metadata.json:**
92
+ - `name`, `version`, `generation_date`, `confidence_tier` used during creation
93
+ - `source_root` — Resolved source code path used during extraction
94
+
95
+ **Detect split-body state:** If a `references/` directory exists and SKILL.md's `## Full` headings are absent or stubs, this is a split-body skill. Flag `split_body: true` in the baseline so downstream steps (especially semantic diff in step 4) know to also read `references/*.md` for complete content comparison.
96
+
97
+ ### 4. Load Provenance Map
98
+
99
+ Search for provenance map at `{forge_data_folder}/{skill_name}/{active_version}/provenance-map.json` (i.e., `{forge_version}/provenance-map.json`). If not found at the versioned path, fall back to `{forge_data_folder}/{skill_name}/provenance-map.json`:
100
+
101
+ **If found:**
102
+ - Record provenance map age (days since last extraction) from file mtime
103
+ - Normalize the map's deterministic projections in one subprocess call:
104
+
105
+ ```bash
106
+ uv run {loadProvenanceScript} normalize {provenanceMap}
107
+ ```
108
+
109
+ Parse the emitted JSON and stash these fields in workflow context (downstream steps read them directly — no re-walk):
110
+ - `{bounded_scan_files}` — sorted POSIX list, union of `entries[].source_file` and `file_entries[].source_file`. Step 2 `re-index.md` consumes this as the bounded scan list.
111
+ - `{is_stack_skill}`, `{legacy_stack_provenance}` — stack-skill flags (see Stack Skill Detection below for downstream branching).
112
+ - `{source_root}`, `{baseline_commit}`, `{baseline_ref}` — used by §5 Resolve Source Path and §5b Detect Upstream Drift.
113
+ - `{reexport_map}` — `{<internal>: <public>}` mapping consumed by `structural-diff.md` §1 to collapse public-API renames before diffing.
114
+
115
+ If the script exits non-zero, surface the stderr as a HARD HALT — the map is structurally invalid and downstream steps cannot proceed.
116
+
117
+ **If missing at both paths:**
118
+ - "No provenance map found for `{skill_name}`. This skill may not have been created by create-skill."
119
+ - "**Degraded mode available:** I can perform text-based comparison without provenance data. Findings will have T1-low confidence."
120
+ - "**[D]egraded mode** — proceed with text-diff only"
121
+ - "**[X]** — abort audit"
122
+ - Wait for user selection. If D, set `degraded_mode: true` and `confidence_mode = "degraded — all findings T1-low"`, then skip the normalize call above (no map to normalize). If X, halt workflow.
123
+
124
+ ### Stack Skill Detection
125
+
126
+ `{is_stack_skill}` and `{legacy_stack_provenance}` are already resolved by the normalize call in §4 — no additional walk needed. Apply the post-detection logic:
127
+
128
+ If `{is_stack_skill}` is true and `constituents` array is present (compose-mode stack):
129
+ - For each constituent, compute the current metadata hash: read `{constituent.skill_path}/active/{constituent.skill_name}/metadata.json` and compute SHA-256
130
+ - Compare against `constituent.metadata_hash`
131
+ - Flag any mismatches as **constituent drift** with severity HIGH
132
+ - Record constituent freshness results for the report
133
+
134
+ If `{legacy_stack_provenance}` is true: log a note that this stack uses v1 provenance format with reduced audit depth (library-level only, no per-export verification).
135
+
136
+ ### 5. Resolve Source Path
137
+
138
+ **If provenance map loaded:**
139
+ - Use `{source_root}` (already extracted by §4 normalize) as source code path
140
+ - Verify source path still exists and is accessible
141
+ - `{baseline_commit}` and `{baseline_ref}` are already populated by §4. If `{baseline_commit}` is null in the projection, fall back to `metadata.source_commit`. `{baseline_ref}` may be a tag, branch, `HEAD`, or `"local"`.
142
+
143
+ **If degraded mode:**
144
+ - Ask user: "Please provide the path to the current source code."
145
+ - `baseline_commit` and `baseline_ref` are unavailable — §5b will short-circuit
146
+
147
+ **Validate:** Confirm source directory exists and contains expected files.
148
+
149
+ ### 5b. Detect Upstream Drift
150
+
151
+ Upstream drift detection is the primary use case of this workflow. If the local clone is still pinned to the baseline commit while upstream has shipped newer tags, auditing against the unchanged tree will misleadingly report CLEAN even after a major release.
152
+
153
+ **Skip this section** if any of the following hold:
154
+ - `baseline_ref` is `"local"`, `null`, or unset (non-git source)
155
+ - `{source_root}` is not a git worktree (`git -C {source_root} rev-parse --git-dir` fails)
156
+ - `baseline_commit` is unavailable
157
+ - Degraded mode is active (no provenance map)
158
+
159
+ When skipping, log the reason, then set the audit-ref context variables to baseline values so step 6 renders a coherent Provenance row: `audit_ref = baseline_ref or "(unknown)"`, `audit_ref_source = "baseline"` (or `"unavailable"` if both `baseline_ref` and `baseline_commit` are unset), `audit_commit = baseline_commit or "(unknown)"`, `latest_tag = null`, `remote_head = null`. Continue to §6.
160
+
161
+ **Otherwise:**
162
+
163
+ 1. **Fetch upstream refs** (read-only, no working-tree mutation):
164
+
165
+ ```bash
166
+ git -C {source_root} fetch --tags --quiet origin
167
+ ```
168
+
169
+ If fetch fails (no network, no remote, detached clone), log the reason, record `upstream_fetch: "failed:{reason}"` in context, set `audit_ref = baseline_ref`, `audit_ref_source = "baseline"`, `audit_commit = baseline_commit`, `latest_tag = null`, `remote_head = null`, and continue to §6 without gating.
170
+
171
+ 2. **Find latest remote ref:**
172
+ - Remote default-branch HEAD: `git -C {source_root} rev-parse origin/HEAD` (fall back to `origin/main` or `origin/master` if the symbolic ref is unavailable) — record as `remote_head`.
173
+ - Newest semver tag: `git -C {source_root} for-each-ref --sort=-v:refname --format='%(refname:short)' 'refs/tags/v*' | head -1` — record as `latest_tag`.
174
+
175
+ 3. **Compare to baseline:**
176
+ - If `baseline_commit` equals the commit that `remote_head` resolves to AND (`latest_tag` is empty OR semver-equals `baseline_ref` OR is older than `baseline_ref`), upstream has not moved. Set `audit_ref = baseline_ref`, `audit_ref_source = "baseline"`, `audit_commit = baseline_commit`. Continue to §6.
177
+ - Otherwise upstream has moved — proceed to the gate.
178
+
179
+ 4. **User gate — Upstream drift detected:**
180
+
181
+ "**Upstream has moved since this skill was created.**
182
+
183
+ | | Baseline | Upstream |
184
+ |---|---|---|
185
+ | Ref | `{baseline_ref}` | `{latest_tag}` (newest tag) / `{remote_head}` (default HEAD) |
186
+ | Commit | `{baseline_commit_short}` | `{latest_tag_commit_short}` / `{remote_head_short}` |
187
+
188
+ Auditing against the baseline clone will report little-to-no structural drift even if the upstream API has changed. Options:
189
+
190
+ - **[C] Checkout-and-audit-against-latest** — checkout `{latest_tag}` (or `{remote_head}` if no newer tag) in `{source_root}` and audit against that. Re-extraction will reflect the current upstream surface.
191
+ - **[S] Stay-on-baseline** — keep `{source_root}` at `{baseline_ref}` and audit structural drift against the unchanged tree. The report will note `audit_ref = baseline`.
192
+ - **[X] Abort** — halt the workflow without producing a report.
193
+
194
+ **Select:** [C] / [S] / [X]"
195
+
196
+ **Gate handling:**
197
+ - **[C]:** Acquire an exclusive lock on `{source_root}/.skf-workspace.lock` (`flock -x` or `fcntl.flock(LOCK_EX)`) before mutating the working tree — matches the concurrency discipline in `src/skf-create-skill/references/source-resolution-protocols.md` and avoids racing with a concurrent create-skill / test-skill run against the same workspace clone. If `flock` is unavailable, emit a warning and proceed.
198
+
199
+ **Dirty-worktree probe (mandatory before checkout).** Run `git -C {source_root} status --porcelain` after acquiring the lock and before the checkout. If the output is non-empty, the working tree has uncommitted changes — `git checkout {chosen_ref}` will abort with `error: Your local changes to the following files would be overwritten by checkout`, halting the workflow mid-step. The most common benign cause is a tooling-generated edit (e.g. the CCC daemon appending a `.cocoindex_code/` line to `.gitignore` after `setup-forge` pointed it at this clone), but the changes could also be the operator's in-progress work. Surface a sub-gate before mutating:
200
+
201
+ "**Working tree has uncommitted changes.** `git status --porcelain` returned:
202
+
203
+ ```
204
+ {first 20 lines of porcelain output, ellipsis if more}
205
+ ```
206
+
207
+ A `git checkout` would abort. Options:
208
+ - **[T] Transient stash** — `git stash push -m 'skf-audit: pre-checkout' --include-untracked`, perform the checkout, and pop the stash on the way out. Recommended when the changes look tooling-generated (e.g. a `.gitignore` line referencing `.cocoindex_code/`, lockfile churn from an indexer).
209
+ - **[A] Abort** — halt the workflow and let the operator commit, stash, or discard manually before retrying.
210
+ - **[F] Force checkout** — `git checkout --force` discards uncommitted changes irrecoverably. Only choose this after confirming the changes are safe to lose."
211
+
212
+ **Gate handling:**
213
+ - **[T]:** Run `git -C {source_root} stash push -m 'skf-audit-skill: pre-checkout {chosen_ref}' --include-untracked`. Capture the stash ref from the command output (e.g. `stash@{0}`) and store as `pre_checkout_stash_ref` in workflow context for step 6 Provenance to surface. Proceed to the checkout. (After audit completes, the operator restores the stash with `git stash pop` — step 6 puts the literal command in the report as a workflow-level convention rather than per-author ad-hoc prose.)
214
+ - **[A]:** HALT the workflow. Do not write a drift report — the audit was never started.
215
+ - **[F]:** Run `git -C {source_root} checkout --force {chosen_ref}` instead of the plain checkout. Record `pre_checkout_force_discard: true` in workflow context for step 6 to surface as a loud warning. Skip the stash path.
216
+ - **Other input:** help user, redisplay the sub-gate.
217
+
218
+ **Headless default** (when `{headless_mode}`): auto-select **[A] Abort** rather than silently mutating the working tree. Emit a loud log line: `"headless: dirty worktree detected at {source_root}; refusing to checkout {chosen_ref} or stash. Re-run interactively to choose [T]/[A]/[F]."` Stashing under automation could lose work if the operator never returns to pop; force-checkout under automation could destroy uncommitted work outright. Abort is the only safe non-interactive default.
219
+
220
+ If `git status --porcelain` is empty, skip the sub-gate and proceed directly to the checkout.
221
+
222
+ Then `git -C {source_root} checkout {chosen_ref}` (prefer `latest_tag` when present, else `remote_head`). Set `audit_ref = {chosen_ref}`, `audit_ref_source = "checkout-latest"`, `audit_commit = git rev-parse HEAD`. Hold the lock through step 2 re-extraction and release only after the extraction snapshot is complete.
223
+ - **[S]:** Keep baseline. Set `audit_ref = baseline_ref`, `audit_ref_source = "baseline"`, `audit_commit = baseline_commit`.
224
+ - **[X]:** HALT workflow — do not create drift report.
225
+ - **Other input:** help user, redisplay gate.
226
+
227
+ **Headless default** (when `{headless_mode}`): auto-select **[S]** and emit a loud log line: `"headless: upstream drift detected ({baseline_ref} → {latest_tag or remote_head}); staying on baseline. Re-run interactively to audit against latest."` Do not check out in headless mode — silent ref changes under automation would mutate the user's working tree without consent.
228
+
229
+ 5. **Record for report:** store `audit_ref`, `audit_ref_source`, `audit_commit`, `latest_tag`, `remote_head`, and `baseline_commit` in context. Step-06 surfaces them in the Provenance section so readers can tell which comparison actually ran.
230
+
231
+ ### 6. Create Drift Report
232
+
233
+ **Re-audit detection (before creating a fresh report).** Glob `{forge_version}/drift-report-*.md`. If one or more matches exist, identify the most recent one by file mtime (or by the `{timestamp}` segment in the filename when mtime is unreliable on the filesystem). If that report's age is `< 7 days` and its frontmatter `audit_ref` matches the current `{audit_ref}` (resolved in §5b), surface a soft gate before creating a fresh report:
234
+
235
+ "**Recent audit found:** `{prior_report_path}` (created {prior_timestamp}, audit_ref=`{audit_ref}`).
236
+
237
+ Options:
238
+ - **[F] Fresh audit** (recommended; default in headless) — start a new drift report at `{outputFile}` and ignore the prior run.
239
+ - **[D] Diff against prior report** — compute findings delta vs the prior report and emit a `## Diff Against Prior Report` subsection in step 6 (report.md).
240
+ - **[R] Resume the prior report** — load the prior report's frontmatter (`stepsCompleted`, `drift_score`, intermediate findings) and jump to the next un-completed step instead of starting over.
241
+
242
+ **Select:** [F] / [D] / [R]"
243
+
244
+ **Gate handling:**
245
+ - **[F]:** Default. Proceed with the fresh-report creation below — ignore the prior report.
246
+ - **[D]:** Read the prior report's findings_list (parse the Structural/Semantic/Severity sections, or the appended findings tables) and stash as `prior_findings` in workflow context. Run the new audit normally. In step 6 (report.md), after the Remediation Suggestions section, emit a `## Diff Against Prior Report` subsection summarizing added / removed / changed findings vs `prior_findings`.
247
+ - **[R]:** Load the prior report's frontmatter (`stepsCompleted`, `drift_score`, any intermediate state). Set `{outputFile}` to the prior report path (do NOT create a new one). Determine the next un-completed step from `stepsCompleted` and skip forward to it; downstream steps append to the existing report.
248
+
249
+ > **Note (resumability):** the existing template frontmatter captures `stepsCompleted` and `drift_score` but does not currently persist intermediate findings_list between stages. If [R] is selected and stepsCompleted indicates the prior run halted after structural-diff or semantic-diff, the appended sections in the report body (`## Structural Drift`, `## Semantic Drift`, `## Severity Classification`) serve as the implicit intermediate state — re-parse them on resume rather than re-running completed stages. **TODO:** if resumability proves unreliable in practice, extend the report frontmatter to carry an explicit `intermediate_findings` block (out of scope for this PR).
250
+
251
+ - **Other input:** help user, redisplay the gate.
252
+
253
+ **Headless default** (when `{headless_mode}`): auto-select **[F]** and emit a loud log line: `"headless: recent audit found at {prior_report_path}; defaulting to fresh audit. Re-run interactively to choose [D]/[R]."`
254
+
255
+ **Skip this gate** if no prior report matches the `< 7 days + same audit_ref` filter — proceed directly to creating the fresh report.
256
+
257
+ **Create the fresh report** (when [F] is selected, headless default fires, or no prior report exists):
258
+
259
+ Create `{outputFile}` from `{templateFile}`:
260
+
261
+ - Populate frontmatter: skill_name, skill_path, source_path, forge_tier, date, user_name
262
+ - Set `stepsCompleted: ['init']`
263
+ - Fill Audit Summary skeleton with loaded baseline data
264
+
265
+ ### 7. Present Baseline Summary (User Gate)
266
+
267
+ "**Audit Baseline Loaded**
268
+
269
+ | Field | Value |
270
+ |-------|-------|
271
+ | **Skill** | {skill_name} v{version} |
272
+ | **Created** | {generation_date} |
273
+ | **Source** | {source_path} |
274
+ | **Forge Tier** | {current_tier} (created at {original_tier}) |
275
+ | **Provenance Age** | {days} days since last extraction |
276
+ | **Export Count** | {count} exports in provenance map |
277
+ | **Mode** | {normal / degraded} |
278
+
279
+ **Analysis plan based on tier:**
280
+ - {Quick: text-diff comparison (T1-low confidence)}
281
+ - {Forge: AST structural comparison (T1 confidence)}
282
+ - {Forge+: AST structural comparison + CCC-assisted rename detection (T1 confidence)}
283
+ - {Deep: AST structural + QMD semantic comparison (T1 + T2 confidence)}
284
+
285
+ **Ready to begin drift analysis?**"
286
+
287
+ ### 8. Present MENU OPTIONS
288
+
289
+ Display: "**Select:** [C] Continue to Analysis"
290
+
291
+ #### Menu Handling Logic:
292
+
293
+ - IF C: Save baseline to {outputFile}, update frontmatter stepsCompleted, then load, read entire file, then execute {nextStepFile}
294
+ - IF Any other: help user, then [Redisplay Menu Options](#8-present-menu-options)
295
+
296
+ #### EXECUTION RULES:
297
+
298
+ - ALWAYS halt and wait for user input after presenting menu
299
+ - **GATE [default: C]** — If `{headless_mode}`: auto-proceed with [C] Continue, log: "headless: auto-continue past baseline confirmation"
300
+ - ONLY proceed to next step when user selects 'C'
301
+
302
+ ## CRITICAL STEP COMPLETION NOTE
303
+
304
+ ONLY WHEN C is selected and the drift report has been created with baseline data populated, will you then load and read fully `{nextStepFile}` to execute and begin source re-indexing.
305
+
@@ -1,8 +1,10 @@
1
1
  ---
2
- nextStepFile: './step-03-structural-diff.md'
2
+ nextStepFile: 'structural-diff.md'
3
3
  outputFile: '{forge_version}/drift-report-{timestamp}.md'
4
4
  ---
5
5
 
6
+ <!-- Config: communicate in {communication_language}. -->
7
+
6
8
  # Step 2: Re-Index Source
7
9
 
8
10
  ## STEP GOAL:
@@ -17,8 +19,6 @@ Re-scan the source code using the current forge tier tools to build a fresh extr
17
19
 
18
20
  ## MANDATORY SEQUENCE
19
21
 
20
- **CRITICAL:** Follow this sequence exactly. Do not skip, reorder, or improvise unless user explicitly requests a change.
21
-
22
22
  ### 1. Determine Extraction Strategy
23
23
 
24
24
  Based on forge tier detected in Step 01:
@@ -47,23 +47,23 @@ Based on forge tier detected in Step 01:
47
47
 
48
48
  ### 2. Build Bounded Scan List
49
49
 
50
- Audit-skill detects drift on files that were in scope during create-skill. The authoritative record of "what was in scope" is the provenance map loaded in step-01. Scan only those files — **audit-skill does NOT discover new files**. New-file detection is the responsibility of `skf-update-skill`, which maintains its own change manifest. To audit a project that has grown new files since creation, run update-skill first, then audit-skill.
50
+ Audit-skill detects drift on files that were in scope during create-skill. The authoritative record of "what was in scope" is the provenance map loaded in step 1. Scan only those files — **audit-skill does NOT discover new files**. New-file detection is the responsibility of `skf-update-skill`, which maintains its own change manifest. To audit a project that has grown new files since creation, run update-skill first, then audit-skill.
51
51
 
52
- **Why bounded:** without this constraint, files that were deliberately excluded by the original brief's scope patterns (test fixtures, vendored code, generated artifacts, demo code, unrelated modules) get scanned on every audit and their exports are flagged by step-03 structural diff as "added" — false-positive drift that obscures real structural changes.
52
+ **Why bounded:** without this constraint, files that were deliberately excluded by the original brief's scope patterns (test fixtures, vendored code, generated artifacts, demo code, unrelated modules) get scanned on every audit and their exports are flagged by step 3 structural diff as "added" — false-positive drift that obscures real structural changes.
53
53
 
54
- **If a provenance map was loaded in step-01** (normal mode):
54
+ **If a provenance map was loaded in step 1** (normal mode):
55
55
 
56
56
  1. Extract the unique set of file paths from the provenance map:
57
57
  - `entries[].source_file` (one path per extracted export)
58
58
  - `file_entries[].source_file` (one path per tracked script/asset, when present)
59
59
  2. Deduplicate the combined list. This is the **bounded scan list**.
60
- 3. Verify each path under `{source_root}`. Files that existed at creation time but are now missing are **not** errors at this stage — keep them in the list so step-03 can classify them as DELETED. Handling missing files is step-03's job, not step-02's.
60
+ 3. Verify each path under `{source_root}`. Files that existed at creation time but are now missing are **not** errors at this stage — keep them in the list so step 3 can classify them as DELETED. Handling missing files is step 3's job, not step 2's.
61
61
  4. Record `bounded_scan: true` and `bounded_scan_source: "provenance-map"` in context for the evidence report.
62
62
  5. Report:
63
63
 
64
64
  "**Bounded scan:** {count} files from provenance map ({provenance_date})."
65
65
 
66
- **If degraded mode** (no provenance map was loaded — user confirmed `[D]egraded mode` at step-01 §4):
66
+ **If degraded mode** (no provenance map was loaded — user confirmed `[D]egraded mode` at step 1 §4):
67
67
 
68
68
  1. Fall back to a source-tree scan: list all source files under `{source_root}` matching the project's primary language extensions (derive from `metadata.json.language` — e.g., `*.ts` / `*.tsx` for typescript, `*.py` for python, `*.rs` for rust, `*.go` for go).
69
69
  2. Apply generic exclusions: `**/tests/**`, `**/test/**`, `**/__tests__/**`, `*.test.*`, `*.spec.*`, `node_modules/**`, `dist/**`, `build/**`, `target/**`, `__pycache__/**`, `.venv/**`, `vendor/**`.
@@ -82,7 +82,7 @@ Audit-skill detects drift on files that were in scope during create-skill. The a
82
82
  3. Records: export name, type, signature, file path, line number, confidence tier
83
83
  4. Returns structured findings to parent
84
84
 
85
- **If a file from the bounded scan list is missing on disk:** record `{file, exports: [], status: "missing"}` and continue — step-03 structural diff will classify exports previously at this path as DELETED.
85
+ **If a file from the bounded scan list is missing on disk:** record `{file, exports: [], status: "missing"}` and continue — step 3 structural diff will classify exports previously at this path as DELETED.
86
86
 
87
87
  **If subprocess unavailable:** Perform extraction in main thread, processing each file sequentially.
88
88
 
@@ -116,7 +116,7 @@ Read the `qmd_collections` registry from `{sidecar_path}/forge-tier.yaml`.
116
116
 
117
117
  Find the collection entry matching the current skill: look for an entry where `skill_name` matches the current skill being audited AND `type` is `"extraction"`.
118
118
 
119
- Three collection states must be handled distinctly (same branching as step-04 §2 — keep them in sync):
119
+ Three collection states must be handled distinctly (same branching as step 4 §2 — keep them in sync):
120
120
 
121
121
  **If a matching extraction collection is found and populated** (pre-query probe via `qmd ls {collection_name}` or equivalent returns one or more files):
122
122
  Query qmd_bridge against the `{skill_name}-extraction` collection for temporal context on each extracted export:
@@ -175,7 +175,7 @@ CCC failures: skip rename detection silently, proceed with standard structural d
175
175
  ### 6. Update Report and Auto-Proceed
176
176
 
177
177
  Update {outputFile} frontmatter:
178
- - Append `'step-02-re-index'` to `stepsCompleted`
178
+ - Append `'re-index'` to `stepsCompleted`
179
179
 
180
180
  ### 7. Present MENU OPTIONS
181
181
 
@@ -1,8 +1,10 @@
1
1
  ---
2
2
  outputFile: '{forge_version}/drift-report-{timestamp}.md'
3
- nextStepFile: './step-07-health-check.md'
3
+ nextStepFile: 'health-check.md'
4
4
  ---
5
5
 
6
+ <!-- Config: communicate in {communication_language}. Drift report prose in {document_output_language}. -->
7
+
6
8
  # Step 6: Generate Report
7
9
 
8
10
  ## STEP GOAL:
@@ -18,8 +20,6 @@ Finalize the drift report by completing the Audit Summary with calculated metric
18
20
 
19
21
  ## MANDATORY SEQUENCE
20
22
 
21
- **CRITICAL:** Follow this sequence exactly. Do not skip, reorder, or improvise unless user explicitly requests a change.
22
-
23
23
  ### 1. Complete Audit Summary
24
24
 
25
25
  Update the ## Audit Summary section at the top of {outputFile} with final calculated values:
@@ -77,10 +77,10 @@ Append to {outputFile}:
77
77
  {IF any CRITICAL or HIGH findings:}
78
78
  **Recommended:** Run `[US] Update Skill` workflow to apply priority remediations automatically.
79
79
 
80
- {IF `audit_ref != baseline_ref` (source version bump detected in step-01 §5b):}
81
- **Version preservation (non-destructive).** `update-skill` preserves the prior version at `{skill_group}/{baseline_version}/` unchanged and writes the new skill to `{skill_group}/{audit_version}/` (see `skf-update-skill/steps-c/step-04-merge.md` §6b, which creates the new version directory and leaves the previous one on disk). The `active` symlink at `{skill_group}/active` repoints to the new version (see `skf-update-skill/steps-c/step-06-write.md` §5b). On the next export, the prior version's export-manifest entry transitions to `status: archived` — files retained for rollback (see `skf-export-skill/steps-c/step-04-update-context.md`). Do **not** recommend `skf-drop-skill` + `skf-create-skill` for a version bump — that destroys the prior version's artifacts.
80
+ {IF `audit_ref != baseline_ref` (source version bump detected in step 1 §5b):}
81
+ **Version preservation (non-destructive).** `update-skill` preserves the prior version at `{skill_group}/{baseline_version}/` unchanged and writes the new skill to `{skill_group}/{audit_version}/` (see `skf-update-skill/references/merge.md` §6b, which creates the new version directory and leaves the previous one on disk). The `active` symlink at `{skill_group}/active` repoints to the new version (see `skf-update-skill/references/write.md` §5b). On the next export, the prior version's export-manifest entry transitions to `status: archived` — files retained for rollback (see `skf-export-skill/references/update-context.md`). Do **not** recommend `skf-drop-skill` + `skf-create-skill` for a version bump — that destroys the prior version's artifacts.
82
82
 
83
- **Surface new entry points for the brief gate.** If the audit observed new top-level modules, renamed package trees, or new public entry points (new `__init__.py`, `index.ts`, `lib.rs`, or equivalent) that were not in the brief's original scope, call them out here. `update-skill` step-02 §1b detects new candidate files via heuristic and prompts `[P]romote` / `[S]kip` / `[U]pdate-brief`; surfacing them in advance makes that gate faster to resolve, or lets the user refine scope via `skf-brief-skill` before running update-skill.
83
+ **Surface new entry points for the brief gate.** If the audit observed new top-level modules, renamed package trees, or new public entry points (new `__init__.py`, `index.ts`, `lib.rs`, or equivalent) that were not in the brief's original scope, call them out here. `update-skill` step 2 §1b detects new candidate files via heuristic and prompts `[P]romote` / `[S]kip` / `[U]pdate-brief`; surfacing them in advance makes that gate faster to resolve, or lets the user refine scope via `skf-brief-skill` before running update-skill.
84
84
 
85
85
  {IF only MEDIUM or LOW findings:}
86
86
  **Optional:** Minor drift detected. Manual updates sufficient, or run `[US] Update Skill` for automated remediation.
@@ -120,7 +120,7 @@ Append to {outputFile}:
120
120
  ### 4. Update Report Frontmatter
121
121
 
122
122
  Update {outputFile} frontmatter:
123
- - Append `'step-06-report'` to `stepsCompleted`
123
+ - Append `'report'` to `stepsCompleted`
124
124
  - Set `drift_score` to final calculated score
125
125
  - Set `nextWorkflow` to `'update-skill'` if CRITICAL or HIGH findings, otherwise leave empty
126
126
 
@@ -170,6 +170,24 @@ Update {outputFile} frontmatter:
170
170
 
171
171
  Write the result contract per `shared/references/output-contract-schema.md`: the per-run record at `{forge_version}/audit-skill-result-{YYYYMMDD-HHmmss}.json` (UTC timestamp, resolution to seconds) and a copy at `{forge_version}/audit-skill-result-latest.json` (stable path for pipeline consumers — copy, not symlink). Include the drift report path in `outputs`; include `drift_count` and `severity` (CLEAN/MINOR/SIGNIFICANT/CRITICAL) in `summary`.
172
172
 
173
+ **Stdout envelope (headless only).** When `{headless_mode}` is true, emit a single-line JSON envelope to **stdout** immediately after the on-disk result contract is written, so chaining workflows can consume `drift_score`, `report_path`, and `next_workflow` from a captured stdout line without polling the filesystem. The shape matches the "Result Contract (Headless)" section in SKILL.md verbatim:
174
+
175
+ ```
176
+ SKF_AUDIT_RESULT_JSON: {"status":"success","skill_name":"{skill_name}","drift_score":"{CLEAN|MINOR|SIGNIFICANT|CRITICAL}","report_path":"{outputFile}","next_workflow":"{update-skill|null}","audit_ref":"{audit_ref}","exit_code":0,"halt_reason":null}
177
+ ```
178
+
179
+ Field rules: `next_workflow` is `"update-skill"` when CRITICAL or HIGH findings exist (matches the frontmatter `nextWorkflow` set in §4), otherwise `null`. `audit_ref` carries the resolved value from step 1 §5b (`baseline_ref` when no upstream drift was detected, `latest_tag` or `remote_head` when the operator chose `[C] Checkout-and-audit-against-latest`).
180
+
181
+ **HALT envelope mirror (headless only).** For every HARD HALT raised in this workflow (skill-not-found at init.md §1, forge-tier missing at §2, source-dir missing at §5, write-failed at §6, user-cancelled at any `[X]` selection), emit the same envelope shape on **stderr** with `status: "error"`, `drift_score: null` (or last known value if classification ran), `report_path: null` if the report write failed, `exit_code` matching the Exit Codes table, and `halt_reason` set to the failure class from the table (`"skill-not-found"`, `"forge-tier-missing"`, `"source-dir-missing"`, `"write-failed"`, `"user-cancelled"`). This is the only signal a wrapping pipeline receives on failure — log it before exiting.
182
+
183
+ **Post-audit hook (optional).** If `{onCompleteCommand}` is non-empty (resolved at SKILL.md On Activation §3 from `workflow.on_complete`), invoke it as:
184
+
185
+ ```bash
186
+ {onCompleteCommand} --result-path={result_json_path}
187
+ ```
188
+
189
+ where `{result_json_path}` is the per-run record path written above (`{forge_version}/audit-skill-result-{YYYYMMDD-HHmmss}.json`). Log success/failure to `workflow_warnings[]` — never fail the workflow on a hook error. The hook runs after the result contract is finalized so notifiers, ticket-tracker integrations, or downstream pipelines see a complete record. When `{onCompleteCommand}` is empty (bundled default), skip the invocation entirely.
190
+
173
191
  ### 6. Chain to Health Check
174
192
 
175
193
  ONLY WHEN the report has been written, presented, and the result contract saved will you then load, read the full file, and execute `{nextStepFile}`. The health-check step is the true terminal step — do not stop here even though the user-facing summary reads as final.
@@ -1,8 +1,10 @@
1
1
  ---
2
- nextStepFile: './step-05-severity-classify.md'
2
+ nextStepFile: 'severity-classify.md'
3
3
  outputFile: '{forge_version}/drift-report-{timestamp}.md'
4
4
  ---
5
5
 
6
+ <!-- Config: communicate in {communication_language}. -->
7
+
6
8
  # Step 4: Semantic Diff
7
9
 
8
10
  ## STEP GOAL:
@@ -18,8 +20,6 @@ Compare QMD knowledge context between the original skill creation and current st
18
20
 
19
21
  ## MANDATORY SEQUENCE
20
22
 
21
- **CRITICAL:** Follow this sequence exactly. Do not skip, reorder, or improvise unless user explicitly requests a change.
22
-
23
23
  ### 1. Check Forge Tier
24
24
 
25
25
  **IF forge tier is Quick, Forge, or Forge+:**
@@ -34,7 +34,7 @@ Append to {outputFile}:
34
34
  Semantic analysis compares QMD knowledge context for meaning-level changes that structural diff cannot detect. To enable semantic diff, run setup with QMD available to unlock Deep tier.
35
35
  ```
36
36
 
37
- Update frontmatter: append `'step-04-semantic-diff'` to `stepsCompleted`
37
+ Update frontmatter: append `'semantic-diff'` to `stepsCompleted`
38
38
 
39
39
  "**Semantic diff skipped (requires Deep tier). Proceeding to severity classification...**"
40
40
 
@@ -55,7 +55,7 @@ Launch a subprocess (Pattern 3 — data operations) that:
55
55
  - Fall through to the **direct-content fallback** below instead of skipping outright.
56
56
  - **Registry entry present and populated.** Use the `name` field from the registry entry as the collection to query. Proceed to bullet 2.
57
57
 
58
- **Direct-content fallback** (used when the collection is registered but empty): load `SKILL.md` and `references/*.md` from the audited skill, then spot-check each documented export against the current source tree under `{source_root}` using the Deep-tier AST tooling this step already requires (ast_bridge; see step-02 §1 "Deep tier"). This fallback is reachable only from Deep tier — §1 short-circuits Quick/Forge/Forge+ before §2 runs, so AST tooling is guaranteed available here. Record findings with confidence label `T1-low-fallback` rather than T2 — this is direct content inspection, not QMD-backed semantic analysis. The step's output schema is otherwise unchanged; set `qmd_collection = null` in the Semantic Drift header and annotate: "Semantic diff ran in direct-content fallback mode — QMD collection was registered but empty."
58
+ **Direct-content fallback** (used when the collection is registered but empty): load `SKILL.md` and `references/*.md` from the audited skill, then spot-check each documented export against the current source tree under `{source_root}` using the Deep-tier AST tooling this step already requires (ast_bridge; see step 2 §1 "Deep tier"). This fallback is reachable only from Deep tier — §1 short-circuits Quick/Forge/Forge+ before §2 runs, so AST tooling is guaranteed available here. Record findings with confidence label `T1-low-fallback` rather than T2 — this is direct content inspection, not QMD-backed semantic analysis. The step's output schema is otherwise unchanged; set `qmd_collection = null` in the Semantic Drift header and annotate: "Semantic diff ran in direct-content fallback mode — QMD collection was registered but empty."
59
59
 
60
60
  2. Queries for knowledge context around each export documented in the skill
61
61
  3. Retrieves: usage patterns, conventions, architectural context, dependency relationships
@@ -128,7 +128,7 @@ Append to {outputFile}:
128
128
  ### 5. Update Report and Auto-Proceed
129
129
 
130
130
  Update {outputFile} frontmatter:
131
- - Append `'step-04-semantic-diff'` to `stepsCompleted`
131
+ - Append `'semantic-diff'` to `stepsCompleted`
132
132
 
133
133
  ### 6. Present MENU OPTIONS
134
134
 
@@ -1,9 +1,11 @@
1
1
  ---
2
- nextStepFile: './step-06-report.md'
2
+ nextStepFile: 'report.md'
3
3
  outputFile: '{forge_version}/drift-report-{timestamp}.md'
4
4
  severityRulesFile: 'references/severity-rules.md'
5
5
  ---
6
6
 
7
+ <!-- Config: communicate in {communication_language}. -->
8
+
7
9
  # Step 5: Severity Classification
8
10
 
9
11
  ## STEP GOAL:
@@ -18,8 +20,6 @@ Grade every drift finding from Steps 03 and 04 by severity level (CRITICAL/HIGH/
18
20
 
19
21
  ## MANDATORY SEQUENCE
20
22
 
21
- **CRITICAL:** Follow this sequence exactly. Do not skip, reorder, or improvise unless user explicitly requests a change.
22
-
23
23
  ### 1. Load Severity Rules
24
24
 
25
25
  Launch a subprocess (Pattern 3 — data operations) that:
@@ -85,7 +85,7 @@ Apply scoring rules from {severityRulesFile}:
85
85
 
86
86
  ### 5. Compile Severity Classification Section
87
87
 
88
- **Rollup inherits from step-03.** If step-03 §5 collapsed ≥ 10 same-kind findings into a single rollup row (deleted source file, renamed module, entire package tree removed), carry that rollup through to the matching severity table as one row — do not re-expand it here. Keep the existing 6-column severity table shape; the rollup encodes root cause, count, and representative symbols **inline in the `Finding` cell** rather than adding new columns, so rollup and per-item rows render cleanly in one table. Changed-signature and cross-file findings remain per-row; they were not eligible for rollup in step-03 and are not eligible here.
88
+ **Rollup inherits from step 3.** If step 3 §5 collapsed ≥ 10 same-kind findings into a single rollup row (deleted source file, renamed module, entire package tree removed), carry that rollup through to the matching severity table as one row — do not re-expand it here. Keep the existing 6-column severity table shape; the rollup encodes root cause, count, and representative symbols **inline in the `Finding` cell** rather than adding new columns, so rollup and per-item rows render cleanly in one table. Changed-signature and cross-file findings remain per-row; they were not eligible for rollup in step 3 and are not eligible here.
89
89
 
90
90
  **Rollup row form (any severity table):**
91
91
 
@@ -138,7 +138,7 @@ Append to {outputFile}:
138
138
  ### 6. Update Report and Auto-Proceed
139
139
 
140
140
  Update {outputFile} frontmatter:
141
- - Append `'step-05-severity-classify'` to `stepsCompleted`
141
+ - Append `'severity-classify'` to `stepsCompleted`
142
142
  - Set `drift_score` to calculated overall score
143
143
 
144
144
  ### 7. Present MENU OPTIONS
@@ -1,3 +1,5 @@
1
+ <!-- Config: communicate in {communication_language}. -->
2
+
1
3
  # Severity Classification Rules
2
4
 
3
5
  ## Severity Levels