bmad-module-skill-forge 1.4.1 → 1.5.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 (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 +147 -16
  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-manifest-ops.py +22 -6
  35. package/src/shared/scripts/skf-merge-ccc-exclusions.py +34 -4
  36. package/src/shared/scripts/skf-pair-intersect.py +250 -0
  37. package/src/shared/scripts/skf-provenance-gap-dispatch.py +433 -0
  38. package/src/shared/scripts/skf-qmd-classify-collections.py +42 -8
  39. package/src/shared/scripts/skf-recommend-scope-type.py +2 -2
  40. package/src/shared/scripts/skf-render-quick-metadata.py +2 -2
  41. package/src/shared/scripts/skf-resolve-authoritative-files.py +504 -0
  42. package/src/shared/scripts/skf-scan-manifests.py +738 -0
  43. package/src/shared/scripts/skf-scan-skill-md-structure.py +375 -0
  44. package/src/shared/scripts/skf-update-active-symlink.py +315 -0
  45. package/src/shared/scripts/skf-validate-brief-inputs.py +5 -5
  46. package/src/shared/scripts/skf-validate-brief-schema.py +348 -0
  47. package/src/shared/scripts/skf-write-skill-brief.py +61 -5
  48. package/src/skf-analyze-source/SKILL.md +69 -16
  49. package/src/skf-analyze-source/assets/skill-brief-schema.md +1 -1
  50. package/src/skf-analyze-source/customize.toml +55 -0
  51. package/src/skf-analyze-source/{steps-c/step-01b-continue.md → references/continue.md} +12 -12
  52. package/src/skf-analyze-source/{steps-c/step-06-generate-briefs.md → references/generate-briefs.md} +29 -10
  53. package/src/skf-analyze-source/{steps-c/step-07-health-check.md → references/health-check.md} +5 -3
  54. package/src/skf-analyze-source/{steps-c/step-03-identify-units.md → references/identify-units.md} +48 -14
  55. package/src/skf-analyze-source/{steps-c/step-01-init.md → references/init.md} +32 -9
  56. package/src/skf-analyze-source/{steps-c/step-04-map-and-detect.md → references/map-and-detect.md} +52 -25
  57. package/src/skf-analyze-source/{steps-c/step-05-recommend.md → references/recommend.md} +15 -8
  58. package/src/skf-analyze-source/{steps-c/step-02-scan-project.md → references/scan-project.md} +16 -10
  59. package/src/skf-analyze-source/references/unit-detection-heuristics.md +2 -0
  60. package/src/skf-analyze-source/templates/analysis-report-template.md +6 -6
  61. package/src/skf-audit-skill/SKILL.md +66 -15
  62. package/src/skf-audit-skill/assets/drift-report-template.md +6 -5
  63. package/src/skf-audit-skill/customize.toml +49 -0
  64. package/src/skf-audit-skill/{steps-c/step-07-health-check.md → references/health-check.md} +5 -3
  65. package/src/skf-audit-skill/{steps-c/step-01-init.md → references/init.md} +63 -19
  66. package/src/skf-audit-skill/{steps-c/step-02-re-index.md → references/re-index.md} +11 -11
  67. package/src/skf-audit-skill/{steps-c/step-06-report.md → references/report.md} +25 -7
  68. package/src/skf-audit-skill/{steps-c/step-04-semantic-diff.md → references/semantic-diff.md} +6 -6
  69. package/src/skf-audit-skill/{steps-c/step-05-severity-classify.md → references/severity-classify.md} +5 -5
  70. package/src/skf-audit-skill/references/severity-rules.md +2 -0
  71. package/src/skf-audit-skill/{steps-c/step-03-structural-diff.md → references/structural-diff.md} +35 -17
  72. package/src/skf-brief-skill/SKILL.md +49 -19
  73. package/src/skf-brief-skill/assets/description-voice-examples.md +1 -1
  74. package/src/skf-brief-skill/assets/skill-brief-schema.md +32 -2
  75. package/src/skf-brief-skill/customize.toml +44 -0
  76. package/src/skf-brief-skill/{steps-c/step-02-analyze-target.md → references/analyze-target.md} +27 -15
  77. package/src/skf-brief-skill/{steps-c/step-04-confirm-brief.md → references/confirm-brief.md} +13 -10
  78. package/src/skf-brief-skill/references/draft-checkpoint.md +4 -4
  79. package/src/skf-brief-skill/{steps-c/step-01-gather-intent.md → references/gather-intent.md} +35 -29
  80. package/src/skf-brief-skill/references/headless-args.md +9 -9
  81. package/src/skf-brief-skill/references/headless-source-authority-detection.md +1 -1
  82. package/src/skf-brief-skill/{steps-c/step-06-health-check.md → references/health-check.md} +4 -2
  83. package/src/skf-brief-skill/references/portfolio-similarity-check.md +2 -2
  84. package/src/skf-brief-skill/references/qmd-collection-registration.md +2 -2
  85. package/src/skf-brief-skill/{steps-c/step-03-scope-definition.md → references/scope-definition.md} +27 -20
  86. package/src/skf-brief-skill/references/version-resolution.md +2 -2
  87. package/src/skf-brief-skill/{steps-c/step-05-write-brief.md → references/write-brief.md} +29 -16
  88. package/src/skf-create-skill/SKILL.md +25 -19
  89. package/src/skf-create-skill/assets/compile-assembly-rules.md +3 -3
  90. package/src/skf-create-skill/assets/skill-sections.md +5 -5
  91. package/src/skf-create-skill/assets/tessl-dismissal-rules.md +11 -11
  92. package/src/skf-create-skill/customize.toml +35 -0
  93. package/src/skf-create-skill/references/authoritative-files-protocol.md +142 -0
  94. package/src/skf-create-skill/{steps-c/step-05-compile.md → references/compile.md} +16 -16
  95. package/src/skf-create-skill/{steps-c/step-03d-component-extraction.md → references/component-extraction.md} +16 -16
  96. package/src/skf-create-skill/{steps-c/step-02-ecosystem-check.md → references/ecosystem-check.md} +4 -4
  97. package/src/skf-create-skill/{steps-c/step-04-enrich.md → references/enrich.md} +3 -3
  98. package/src/skf-create-skill/{steps-c/step-03-extract.md → references/extract.md} +52 -120
  99. package/src/skf-create-skill/references/extraction-patterns.md +10 -8
  100. package/src/skf-create-skill/{steps-c/step-07-generate-artifacts.md → references/generate-artifacts.md} +11 -11
  101. package/src/skf-create-skill/{steps-c/step-09-health-check.md → references/health-check.md} +4 -2
  102. package/src/skf-create-skill/{steps-c/step-01-load-brief.md → references/load-brief.md} +40 -32
  103. package/src/skf-create-skill/{steps-c/step-08-report.md → references/report.md} +8 -8
  104. package/src/skf-create-skill/references/source-resolution-protocols.md +6 -6
  105. package/src/skf-create-skill/{steps-c/sub/step-02b-ccc-discover.md → references/sub/ccc-discover.md} +5 -5
  106. package/src/skf-create-skill/{steps-c/sub/step-03c-fetch-docs.md → references/sub/fetch-docs.md} +28 -12
  107. package/src/skf-create-skill/{steps-c/sub/step-03b-fetch-temporal.md → references/sub/fetch-temporal.md} +81 -50
  108. package/src/skf-create-skill/{steps-c/step-06-validate.md → references/validate.md} +48 -28
  109. package/src/skf-create-stack-skill/SKILL.md +76 -17
  110. package/src/skf-create-stack-skill/assets/provenance-map-schema.md +102 -0
  111. package/src/skf-create-stack-skill/assets/stack-skill-template.md +1 -1
  112. package/src/skf-create-stack-skill/customize.toml +46 -0
  113. package/src/skf-create-stack-skill/{steps-c/step-06-compile-stack.md → references/compile-stack.md} +6 -5
  114. package/src/skf-create-stack-skill/references/compose-mode-rules.md +3 -1
  115. package/src/skf-create-stack-skill/{steps-c/step-05-detect-integrations.md → references/detect-integrations.md} +37 -11
  116. package/src/skf-create-stack-skill/{steps-c/step-02-detect-manifests.md → references/detect-manifests.md} +32 -28
  117. package/src/skf-create-stack-skill/{steps-c/step-07-generate-output.md → references/generate-output.md} +11 -85
  118. package/src/skf-create-stack-skill/{steps-c/step-10-health-check.md → references/health-check.md} +4 -2
  119. package/src/skf-create-stack-skill/{steps-c/step-01-init.md → references/init.md} +70 -4
  120. package/src/skf-create-stack-skill/references/integration-patterns.md +2 -0
  121. package/src/skf-create-stack-skill/references/manifest-patterns.md +2 -0
  122. package/src/skf-create-stack-skill/{steps-c/step-04-parallel-extract.md → references/parallel-extract.md} +44 -17
  123. package/src/skf-create-stack-skill/{steps-c/step-03-rank-and-confirm.md → references/rank-and-confirm.md} +5 -4
  124. package/src/skf-create-stack-skill/{steps-c/step-09-report.md → references/report.md} +3 -3
  125. package/src/skf-create-stack-skill/{steps-c/step-08-validate.md → references/validate.md} +6 -6
  126. package/src/skf-drop-skill/SKILL.md +84 -12
  127. package/src/skf-drop-skill/customize.toml +57 -0
  128. package/src/skf-drop-skill/{steps-c/step-02-execute.md → references/execute.md} +49 -34
  129. package/src/skf-drop-skill/{steps-c/step-04-health-check.md → references/health-check.md} +6 -4
  130. package/src/skf-drop-skill/{steps-c/step-03-report.md → references/report.md} +13 -5
  131. package/src/skf-drop-skill/{steps-c/step-01-select.md → references/select.md} +63 -15
  132. package/src/skf-export-skill/SKILL.md +85 -16
  133. package/src/skf-export-skill/assets/managed-section-format.md +3 -3
  134. package/src/skf-export-skill/assets/snippet-format.md +2 -2
  135. package/src/skf-export-skill/customize.toml +49 -0
  136. package/src/skf-export-skill/{steps-c/step-03-generate-snippet.md → references/generate-snippet.md} +11 -11
  137. package/src/skf-export-skill/{steps-c/step-07-health-check.md → references/health-check.md} +6 -4
  138. package/src/skf-export-skill/{steps-c/step-01-load-skill.md → references/load-skill.md} +11 -49
  139. package/src/skf-export-skill/references/manifest-rebuild.md +68 -0
  140. package/src/skf-export-skill/references/multi-skill-mode.md +38 -0
  141. package/src/skf-export-skill/references/orphan-context-detection.md +75 -0
  142. package/src/skf-export-skill/references/orphan-row-detection.md +102 -0
  143. package/src/skf-export-skill/{steps-c/step-02-package.md → references/package.md} +7 -7
  144. package/src/skf-export-skill/references/preflight-snippet-root-probe.md +79 -0
  145. package/src/skf-export-skill/{steps-c/step-06-summary.md → references/summary.md} +23 -11
  146. package/src/skf-export-skill/{steps-c/step-05-token-report.md → references/token-report.md} +5 -5
  147. package/src/skf-export-skill/{steps-c/step-04-update-context.md → references/update-context.md} +109 -113
  148. package/src/skf-quick-skill/SKILL.md +63 -123
  149. package/src/skf-quick-skill/customize.toml +44 -0
  150. package/src/skf-quick-skill/references/batch-mode.md +102 -0
  151. package/src/skf-quick-skill/{steps-c/step-04-compile.md → references/compile.md} +10 -10
  152. package/src/skf-quick-skill/{steps-c/step-02-ecosystem-check.md → references/ecosystem-check.md} +5 -5
  153. package/src/skf-quick-skill/{steps-c/step-06-finalize.md → references/finalize.md} +7 -7
  154. package/src/skf-quick-skill/{steps-c/step-07-health-check.md → references/health-check.md} +3 -3
  155. package/src/skf-quick-skill/{steps-c/step-03-quick-extract.md → references/quick-extract.md} +5 -5
  156. package/src/skf-quick-skill/references/registry-resolution.md +2 -0
  157. package/src/skf-quick-skill/{steps-c/step-01-resolve-target.md → references/resolve-target.md} +14 -10
  158. package/src/skf-quick-skill/{steps-c/step-05-write-and-validate.md → references/write-and-validate.md} +4 -4
  159. package/src/skf-refine-architecture/SKILL.md +86 -16
  160. package/src/skf-refine-architecture/customize.toml +49 -0
  161. package/src/skf-refine-architecture/{steps-c/step-05-compile.md → references/compile.md} +4 -4
  162. package/src/skf-refine-architecture/{steps-c/step-02-gap-analysis.md → references/gap-analysis.md} +5 -5
  163. package/src/skf-refine-architecture/{steps-c/step-07-health-check.md → references/health-check.md} +6 -4
  164. package/src/skf-refine-architecture/{steps-c/step-04-improvements.md → references/improvements.md} +5 -5
  165. package/src/skf-refine-architecture/references/init.md +144 -0
  166. package/src/skf-refine-architecture/{steps-c/step-03-issue-detection.md → references/issue-detection.md} +5 -5
  167. package/src/skf-refine-architecture/references/refinement-rules.md +2 -0
  168. package/src/skf-refine-architecture/{steps-c/step-06-report.md → references/report.md} +14 -5
  169. package/src/skf-rename-skill/SKILL.md +82 -12
  170. package/src/skf-rename-skill/customize.toml +52 -0
  171. package/src/skf-rename-skill/{steps-c/step-02-execute.md → references/execute.md} +94 -99
  172. package/src/skf-rename-skill/references/health-check.md +30 -0
  173. package/src/skf-rename-skill/references/rebuild-context.md +110 -0
  174. package/src/skf-rename-skill/{steps-c/step-03-report.md → references/report.md} +13 -5
  175. package/src/skf-rename-skill/{steps-c/step-01-select.md → references/select.md} +59 -20
  176. package/src/skf-setup/SKILL.md +35 -35
  177. package/src/skf-setup/customize.toml +33 -0
  178. package/src/skf-setup/{steps-c/step-03-auto-index.md → references/auto-index.md} +10 -18
  179. package/src/skf-setup/{steps-c/step-01b-ccc-index.md → references/ccc-index.md} +16 -31
  180. package/src/skf-setup/{steps-c/step-01-detect-and-tier.md → references/detect-and-tier.md} +23 -10
  181. package/src/skf-setup/{steps-c/step-05-health-check.md → references/health-check.md} +1 -1
  182. package/src/skf-setup/{steps-c/step-04-report.md → references/report.md} +21 -19
  183. package/src/skf-setup/references/tier-rules.md +1 -1
  184. package/src/skf-setup/{steps-c/step-02-write-config.md → references/write-config.md} +14 -13
  185. package/src/skf-test-skill/SKILL.md +77 -15
  186. package/src/skf-test-skill/customize.toml +54 -0
  187. package/src/skf-test-skill/{steps-c/step-04-coherence-check.md → references/coherence-check.md} +37 -73
  188. package/src/skf-test-skill/{steps-c/step-03-coverage-check.md → references/coverage-check.md} +16 -39
  189. package/src/skf-test-skill/{steps-c/step-02-detect-mode.md → references/detect-mode.md} +4 -26
  190. package/src/skf-test-skill/{steps-c/step-04b-external-validators.md → references/external-validators.md} +6 -28
  191. package/src/skf-test-skill/references/health-check.md +14 -0
  192. package/src/skf-test-skill/{steps-c/step-01-init.md → references/init.md} +21 -37
  193. package/src/skf-test-skill/references/migration-section-rules.md +4 -2
  194. package/src/skf-test-skill/{steps-c/step-06-report.md → references/report.md} +41 -51
  195. package/src/skf-test-skill/{steps-c/step-05-score.md → references/score.md} +26 -43
  196. package/src/skf-test-skill/references/scoring-rules.md +8 -6
  197. package/src/skf-test-skill/references/source-access-protocol.md +7 -5
  198. package/src/skf-test-skill/scripts/compute-score.py +88 -17
  199. package/src/skf-test-skill/templates/test-report-template.md +13 -13
  200. package/src/skf-update-skill/SKILL.md +23 -14
  201. package/src/skf-update-skill/customize.toml +44 -0
  202. package/src/skf-update-skill/{steps-c/step-02-detect-changes.md → references/detect-changes.md} +176 -68
  203. package/src/skf-update-skill/references/health-check.md +32 -0
  204. package/src/skf-update-skill/{steps-c/step-01-init.md → references/init.md} +56 -8
  205. package/src/skf-update-skill/references/manual-section-rules.md +4 -0
  206. package/src/skf-update-skill/references/merge-conflict-rules.md +4 -0
  207. package/src/skf-update-skill/{steps-c/step-04-merge.md → references/merge.md} +8 -8
  208. package/src/skf-update-skill/{steps-c/step-03-re-extract.md → references/re-extract.md} +53 -44
  209. package/src/skf-update-skill/references/remote-source-resolution.md +5 -1
  210. package/src/skf-update-skill/references/report.md +214 -0
  211. package/src/skf-update-skill/{steps-c/step-05-validate.md → references/validate.md} +5 -5
  212. package/src/skf-update-skill/{steps-c/step-06-write.md → references/write.md} +73 -51
  213. package/src/skf-verify-stack/SKILL.md +89 -17
  214. package/src/skf-verify-stack/assets/feasibility-report-template.md +4 -4
  215. package/src/skf-verify-stack/customize.toml +50 -0
  216. package/src/skf-verify-stack/references/coverage-patterns.md +2 -2
  217. package/src/skf-verify-stack/{steps-c/step-02-coverage.md → references/coverage.md} +13 -9
  218. package/src/skf-verify-stack/{steps-c/step-07-health-check.md → references/health-check.md} +7 -5
  219. package/src/skf-verify-stack/references/init.md +170 -0
  220. package/src/skf-verify-stack/references/integration-verification-rules.md +1 -1
  221. package/src/skf-verify-stack/{steps-c/step-03-integrations.md → references/integrations.md} +18 -14
  222. package/src/skf-verify-stack/{steps-c/step-06-report.md → references/report.md} +27 -42
  223. package/src/skf-verify-stack/{steps-c/step-04-requirements.md → references/requirements.md} +13 -9
  224. package/src/skf-verify-stack/{steps-c/step-05-synthesize.md → references/synthesize.md} +14 -10
  225. package/tools/validate-docs-drift.js +1 -1
  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
@@ -2,13 +2,21 @@
2
2
  briefSchemaFile: 'assets/skill-brief-schema.md'
3
3
  versionResolutionFile: 'references/version-resolution.md'
4
4
  qmdRegistrationFile: 'references/qmd-collection-registration.md'
5
- nextStepFile: './step-06-health-check.md'
6
- writeSkillBriefScript: '{project-root}/src/shared/scripts/skf-write-skill-brief.py'
7
- emitBriefEnvelopeScript: '{project-root}/src/shared/scripts/skf-emit-brief-result-envelope.py'
8
- forgeTierRwScript: '{project-root}/src/shared/scripts/skf-forge-tier-rw.py'
5
+ nextStepFile: 'health-check.md'
6
+ writeSkillBriefProbeOrder:
7
+ - '{project-root}/_bmad/skf/shared/scripts/skf-write-skill-brief.py'
8
+ - '{project-root}/src/shared/scripts/skf-write-skill-brief.py'
9
+ emitBriefEnvelopeProbeOrder:
10
+ - '{project-root}/_bmad/skf/shared/scripts/skf-emit-brief-result-envelope.py'
11
+ - '{project-root}/src/shared/scripts/skf-emit-brief-result-envelope.py'
12
+ forgeTierRwProbeOrder:
13
+ - '{project-root}/_bmad/skf/shared/scripts/skf-forge-tier-rw.py'
14
+ - '{project-root}/src/shared/scripts/skf-forge-tier-rw.py'
9
15
  forgeTierFile: '{sidecar_path}/forge-tier.yaml'
10
16
  ---
11
17
 
18
+ <!-- Config: communicate in {communication_language}. -->
19
+
12
20
  # Step 5: Write Brief
13
21
 
14
22
  ## STEP GOAL:
@@ -26,11 +34,11 @@ To generate the complete skill-brief.yaml from the approved brief data and write
26
34
 
27
35
  ## MANDATORY SEQUENCE
28
36
 
29
- **CRITICAL:** Follow this sequence exactly. Do not skip, reorder, or improvise unless user explicitly requests a change.
30
-
31
37
  ### 1. Reference the Schema (LLM context only)
32
38
 
33
- `{briefSchemaFile}` and `{versionResolutionFile}` document the brief contract for human readers. The deterministic enforcement of that contract lives in `{writeSkillBriefScript}` and its JSON Schema artifact at `src/shared/scripts/schemas/skill-brief.v1.json`. Load `{briefSchemaFile}` only if you need to explain a specific field to the user during inline adjustments — otherwise skip the read; the script is the source of truth.
39
+ **Resolve `{writeSkillBriefHelper}`** from `{writeSkillBriefProbeOrder}`; first existing path wins. HALT if no candidate exists.
40
+
41
+ `{briefSchemaPath}` and `{versionResolutionFile}` document the brief contract for human readers. The deterministic enforcement of that contract lives in `{writeSkillBriefHelper}` and its JSON Schema artifact at `src/shared/scripts/schemas/skill-brief.v1.json`. Load `{briefSchemaPath}` only if you need to explain a specific field to the user during inline adjustments — otherwise skip the read; the script is the source of truth.
34
42
 
35
43
  ### 2. Resolve Output Path
36
44
 
@@ -52,7 +60,7 @@ If the file exists, present:
52
60
  Overwrite it with the brief you just approved? [Y/N]"
53
61
 
54
62
  - **[Y]** Overwrite — proceed to §3.
55
- - **[N]** Cancel — emit a single-line stderr log `brief-skill: overwrite-cancelled at {path}` and HALT with exit code 5 (do not chain to step-06; the run produced no new artifact).
63
+ - **[N]** Cancel — emit a single-line stderr log `brief-skill: overwrite-cancelled at {path}` and HALT with exit code 5 (do not chain to step 6; the run produced no new artifact).
56
64
 
57
65
  **Headless (`{headless_mode}` is true):**
58
66
 
@@ -83,6 +91,7 @@ Assemble the brief context as a **flat** JSON object — every approved value is
83
91
  "scope_include": ["{approved include patterns}"],
84
92
  "scope_exclude": ["{approved exclude patterns}"],
85
93
  "scope_notes": "{approved scope notes or empty string}",
94
+ "scope_rationale": null | {"recommended":"...","chosen":"...","accepted_recommendation":true|false,"heuristic":"...","reason":"...","recorded":"YYYY-MM-DD"},
86
95
  "doc_urls": null | [{"url": "...", "label": "..."}],
87
96
  "scripts_intent": null | "{detect|none|free-text}",
88
97
  "assets_intent": null | "{detect|none|free-text}",
@@ -93,7 +102,7 @@ Assemble the brief context as a **flat** JSON object — every approved value is
93
102
  Pipe it into the writer script with the `--from-flat` flag:
94
103
 
95
104
  ```bash
96
- echo '<context-json>' | uv run {writeSkillBriefScript} write --target {resolved-target-path} --from-flat
105
+ echo '<context-json>' | uv run {writeSkillBriefHelper} write --target {resolved-target-path} --from-flat
97
106
  ```
98
107
 
99
108
  The script translates flat → nested internally, drops the null optional fields, and runs the same schema validation and atomic write as before — pass every key always, the writer decides what reaches the YAML.
@@ -116,38 +125,42 @@ The script:
116
125
 
117
126
  **On success:** capture `brief_path` and `version` from the response envelope — both are needed for §4b and §6.
118
127
 
119
- **Draft cleanup.** After a successful write, remove `{forge_data_folder}/{skill-name}/.brief-draft.json` if it exists (`rm -f` — silent on absent). The draft was a step-01 §7 checkpoint covering the in-flight workflow window; once the brief is written it is no longer meaningful. In headless mode this rm is a no-op (drafts are only written interactively).
128
+ **Draft cleanup.** After a successful write, remove `{forge_data_folder}/{skill-name}/.brief-draft.json` if it exists (`rm -f` — silent on absent). The draft was a step 1 §7 checkpoint covering the in-flight workflow window; once the brief is written it is no longer meaningful. In headless mode this rm is a no-op (drafts are only written interactively).
120
129
 
121
130
  ### 4b. Headless Result Envelope (Canonical)
122
131
 
123
- This section is the canonical envelope-emission reference for the workflow. Every headless emission — the success terminal here and every HARD HALT in step-01/02/05 uses this contract. Remote sites point here instead of restating it.
132
+ **Resolve `{emitBriefEnvelopeHelper}`** from `{emitBriefEnvelopeProbeOrder}`; first existing path wins. HALT if no candidate exists.
133
+
134
+ This section is the canonical envelope-emission reference for the workflow. Every headless emission — the success terminal here and every HARD HALT in step 1/02/05 — uses this contract. Remote sites point here instead of restating it.
124
135
 
125
136
  **Success (this call site only — emitted from §3 directly):**
126
137
 
127
138
  ```bash
128
139
  echo '{"status":"success","brief_path":"<from §3 response>","skill_name":"<name>","version":"<from §3 response>","language":"<language>","scope_type":"<scope.type>","halt_reason":null}' | \
129
- uv run {emitBriefEnvelopeScript} emit
140
+ uv run {emitBriefEnvelopeHelper} emit
130
141
  ```
131
142
 
132
143
  **Error (used by every HARD HALT site):**
133
144
 
134
145
  ```bash
135
146
  echo '{"status":"error","skill_name":"<name>","halt_reason":"<reason>"}' | \
136
- uv run {emitBriefEnvelopeScript} emit --target stderr
147
+ uv run {emitBriefEnvelopeHelper} emit --target stderr
137
148
  ```
138
149
 
139
- When the HALT fires before `skill_name` has been resolved (step-01 §1 pre-flight write probe, step-01 §8 input-missing on a malformed args bundle), pass the partially-gathered value or the literal `"unknown"` — the script accepts any non-empty string at this position.
150
+ When the HALT fires before `skill_name` has been resolved (step 1 §1 pre-flight write probe, step 1 §8 input-missing on a malformed args bundle), pass the partially-gathered value or the literal `"unknown"` — the script accepts any non-empty string at this position.
140
151
 
141
152
  The script derives `exit_code` deterministically from `halt_reason` (null→0, input-missing/input-invalid→2, forge-tier-missing/target-inaccessible/gh-auth-failed→3, write-failed→4, overwrite-cancelled→5, user-cancelled→6 [interactive-only — headless never raises this]), validates against `src/shared/scripts/schemas/skf-brief-result-envelope.v1.json`, and prints the prefixed `SKF_BRIEF_RESULT_JSON: {…}` line.
142
153
 
143
- The script enforces the success/error halt_reason invariant (success requires null halt_reason; error requires non-null). The `user-cancelled` halt_reason is accepted for completeness (interactive `[X]` Cancel sites in step-01/03/04) but never appears on the headless code path.
154
+ The script enforces the success/error halt_reason invariant (success requires null halt_reason; error requires non-null). The `user-cancelled` halt_reason is accepted for completeness (interactive `[X]` Cancel sites in step 1/03/04) but never appears on the headless code path.
144
155
 
145
- Invocation sites (each pointed at this block, not duplicated): step-01 §1 (write-failed pre-resolution), step-01 §8 (input-missing/input-invalid GATE), step-05 §2b (overwrite-cancelled), step-05 §3 (input-invalid/write-failed from script). Step-01 §1 forge-tier-missing and step-02 §1 (target-inaccessible/gh-auth-failed) currently HALT without emitting an envelope — pre-existing gaps tracked separately, not addressed by this canonicalization.
156
+ Invocation sites (each pointed at this block, not duplicated): step 1 §1 (write-failed pre-resolution), step 1 §8 (input-missing/input-invalid GATE), step 5 §2b (overwrite-cancelled), step 5 §3 (input-invalid/write-failed from script). Step-01 §1 forge-tier-missing and step 2 §1 (target-inaccessible/gh-auth-failed) currently HALT without emitting an envelope — pre-existing gaps tracked separately, not addressed by this canonicalization.
146
157
 
147
158
  When `{headless_mode}` is false, skip this section silently — no envelope is emitted.
148
159
 
149
160
  ### 5. QMD Collection Registration (Deep Tier Only)
150
161
 
162
+ **Resolve `{forgeTierRwHelper}`** from `{forgeTierRwProbeOrder}`; first existing path wins. HALT if no candidate exists.
163
+
151
164
  **IF forge tier is Deep AND QMD tool is available:** load `{qmdRegistrationFile}` and follow the procedure there to index the brief into a QMD collection and update the forge-tier registry.
152
165
 
153
166
  **IF forge tier is NOT Deep OR QMD is not available:** skip this section silently — do not load `{qmdRegistrationFile}`. No messaging.
@@ -9,6 +9,14 @@ description: Compile a skill from a brief. Supports --batch for multiple briefs.
9
9
 
10
10
  Compiles a verified agent skill from a skill-brief.yaml and source code, producing an agentskills.io-compliant SKILL.md with provenance map, evidence report, and progressive disclosure references. The workflow is mostly autonomous with three interaction points — after ecosystem check (if match found), after source extraction (to confirm findings), and after content quality review (when tessl produces suggestions). Steps adapt behavior based on forge tier (Quick/Forge/Forge+/Deep). Zero hallucination tolerance: every instruction in the output must trace to source code with a confidence tier citation.
11
11
 
12
+ ## Conventions
13
+
14
+ - Bare paths (e.g. `references/<name>.md`) resolve from the skill root.
15
+ - `references/` holds prompt content carved out of SKILL.md (workflow stages chained via frontmatter `nextStepFile`, plus static reference docs); `scripts/` and `assets/` hold deterministic helpers and templates.
16
+ - `{skill-root}` resolves to this skill's installed directory (where `customize.toml` lives, if present).
17
+ - `{project-root}`-prefixed paths resolve from the project working directory.
18
+ - `{skill-name}` resolves to the skill directory's basename.
19
+
12
20
  ## Role
13
21
 
14
22
  You are operating in Ferris Architect mode — a skill compilation engine performing structural extraction and assembly. Apply zero hallucination tolerance: uncitable content is excluded, not guessed.
@@ -18,8 +26,6 @@ You are operating in Ferris Architect mode — a skill compilation engine perfor
18
26
  These rules apply to every step in this workflow:
19
27
 
20
28
  - Never include content in SKILL.md that cannot be cited to source code
21
- - Read each step file completely before taking any action
22
- - Follow the mandatory sequence in each step exactly — do not skip, reorder, or optimize
23
29
  - Only load one step file at a time — never preload future steps
24
30
  - Always communicate in `{communication_language}`
25
31
  - If `{headless_mode}` is true, auto-proceed through confirmation gates with their default action and log each auto-decision
@@ -28,28 +34,28 @@ These rules apply to every step in this workflow:
28
34
 
29
35
  | # | Step | File | Auto-proceed |
30
36
  |---|------|------|--------------|
31
- | 1 | Load Brief | steps-c/step-01-load-brief.md | Yes |
32
- | 2 | Ecosystem Check | steps-c/step-02-ecosystem-check.md | Conditional |
33
- | 2b | CCC Discover | steps-c/sub/step-02b-ccc-discover.md | Yes |
34
- | 3 | Extract | steps-c/step-03-extract.md | No (confirm) |
35
- | 3b | Fetch Temporal | steps-c/sub/step-03b-fetch-temporal.md | Yes |
36
- | 3c | Fetch Docs | steps-c/sub/step-03c-fetch-docs.md | Yes |
37
- | 3d | Component Extraction | steps-c/step-03d-component-extraction.md | Conditional |
38
- | 4 | Enrich | steps-c/step-04-enrich.md | Yes |
39
- | 5 | Compile | steps-c/step-05-compile.md | Yes |
40
- | 6 | Validate | steps-c/step-06-validate.md | Conditional |
41
- | 7 | Generate Artifacts | steps-c/step-07-generate-artifacts.md | Yes |
42
- | 8 | Report | steps-c/step-08-report.md | Yes |
43
- | 9 | Workflow Health Check | steps-c/step-09-health-check.md | Yes |
44
-
45
- *Sub-steps under `steps-c/sub/` are conditional branches (CCC discovery, temporal/doc enrichment) kept out of the top-level step count so main-line steps 1–9 drive the workflow. Step 3d (Component Extraction) stays top-level as an alternative main step that replaces the standard extraction path when `scope.type: "component-library"`.*
37
+ | 1 | Load Brief | references/load-brief.md | Yes |
38
+ | 2 | Ecosystem Check | references/ecosystem-check.md | Conditional |
39
+ | 2b | CCC Discover | references/sub/ccc-discover.md | Yes |
40
+ | 3 | Extract | references/extract.md | No (confirm) |
41
+ | 3b | Fetch Temporal | references/sub/fetch-temporal.md | Yes |
42
+ | 3c | Fetch Docs | references/sub/fetch-docs.md | Yes |
43
+ | 3d | Component Extraction | references/component-extraction.md | Conditional |
44
+ | 4 | Enrich | references/enrich.md | Yes |
45
+ | 5 | Compile | references/compile.md | Yes |
46
+ | 6 | Validate | references/validate.md | Conditional |
47
+ | 7 | Generate Artifacts | references/generate-artifacts.md | Yes |
48
+ | 8 | Report | references/report.md | Yes |
49
+ | 9 | Workflow Health Check | references/health-check.md | Yes |
50
+
51
+ *Sub-steps under `references/sub/` are conditional branches (CCC discovery, temporal/doc enrichment) kept out of the top-level step count so main-line steps 1–9 drive the workflow. Step 3d (Component Extraction) stays top-level as an alternative main step that replaces the standard extraction path when `scope.type: "component-library"`.*
46
52
 
47
53
  ## Invocation Contract
48
54
 
49
55
  | Aspect | Detail |
50
56
  |--------|--------|
51
57
  | **Inputs** | brief_path (path to skill-brief.yaml) [required], --batch [optional] |
52
- | **Gates** | step-02: Choice Gate [P] (if match) | step-03: Review Gate [C] |
58
+ | **Gates** | step 2: Choice Gate [P] (if match) | step 3: Review Gate [C] |
53
59
  | **Outputs** | SKILL.md, context-snippet.md, metadata.json, provenance-map.json, evidence-report.md, references/ |
54
60
  | **Headless** | All gates auto-resolve with default action when `{headless_mode}` is true |
55
61
 
@@ -60,4 +66,4 @@ These rules apply to every step in this workflow:
60
66
 
61
67
  2. **Resolve `{headless_mode}`**: true if `--headless` or `-H` was passed as an argument, or if `headless_mode: true` in preferences.yaml. Default: false.
62
68
 
63
- 3. Load, read the full file, and then execute `./steps-c/step-01-load-brief.md` to begin the workflow.
69
+ 3. Load, read the full file, and then execute `references/load-brief.md` to begin the workflow.
@@ -21,7 +21,7 @@ description: >
21
21
  - Uppercase placeholders are also acceptable: `NAME`, `COMPONENT_ID`.
22
22
  - For code-ish fragments, use curly braces in place of angle brackets inside the backticks: `` `Meta{typeof X}` ``, `` `Array{T}` ``.
23
23
 
24
- Authors should not rely on remembering this — step-05 §2a enforces it via a pre-write sanitization pass that unconditionally replaces every `<` with `{` and every `>` with `}` in the frontmatter `description`. See step-05 §2a for the rule and `assets/tessl-dismissal-rules.md` (`description-xml-tags-guarded-upstream`) for the recovery path if a downstream tool rewrites the description after §2a has run.
24
+ Authors should not rely on remembering this — step 5 §2a enforces it via a pre-write sanitization pass that unconditionally replaces every `<` with `{` and every `>` with `}` in the frontmatter `description`. See step 5 §2a for the rule and `assets/tessl-dismissal-rules.md` (`description-xml-tags-guarded-upstream`) for the recovery path if a downstream tool rewrites the description after §2a has run.
25
25
  - Only `name` and `description` in frontmatter — `version` and `author` go in metadata.json
26
26
  - No other frontmatter fields for standard skills (only `name`, `description`, `license`, `compatibility`, `metadata`, `allowed-tools` are permitted by spec)
27
27
 
@@ -62,7 +62,7 @@ These sections form the essential standalone body. Target: **under 300 lines tot
62
62
  - Provenance citation per function
63
63
 
64
64
  **Section 4b — Migration & Deprecation Warnings (~10 lines, Deep tier only):**
65
- - Only populated when step-04 enrichment produced **T2-future** annotations (deprecation warnings, breaking changes, planned renames)
65
+ - Only populated when step 4 enrichment produced **T2-future** annotations (deprecation warnings, breaking changes, planned renames)
66
66
  - List each warning as a single-line bullet: function name, what changed or will change, source citation
67
67
  - Max 10 lines — just the actionable warnings, not full context
68
68
  - Link to Tier 2 Full API Reference for details: "See Full API Reference for migration details."
@@ -158,7 +158,7 @@ Replace the function table with a Component Catalog organized by category:
158
158
  **Total components:** {unique count} | {Per variant: **With {name}:** {count}}
159
159
  ```
160
160
 
161
- Source: `component_catalog[]` from step-03d. Group by `category` field. Provenance: cite the registry file.
161
+ Source: `component_catalog[]` from step 3d. Group by `category` field. Provenance: cite the registry file.
162
162
 
163
163
  **Section 5 (Key Types) — Props-focused override:**
164
164
 
@@ -76,7 +76,7 @@ When `scope.type: "component-library"`, these section formats replace their stan
76
76
  **Total components:** {unique_count} | **With {variant1}:** {count1} | **With {variant2}:** {count2}
77
77
  ```
78
78
 
79
- - Source: `component_catalog[]` from step-03d extraction
79
+ - Source: `component_catalog[]` from step 3d extraction
80
80
  - Group by `category` field from registry
81
81
  - Show top 3-5 component names per category
82
82
  - Cite registry file: `[SRC:{registry_file}:L1]`
@@ -224,7 +224,7 @@ Indexed pipe-delimited format for CLAUDE.md managed section (~80-120 tokens per
224
224
  "total_coverage": 0.0,
225
225
  "scripts_count": 0,
226
226
  "assets_count": 0
227
- // "effective_denominator": 0 // optional — emitted for stratified-scope monorepo packages; test-skill uses this as the coverage denominator when present. See step-05-compile.md §4 emit rules.
227
+ // "effective_denominator": 0 // optional — emitted for stratified-scope monorepo packages; test-skill uses this as the coverage denominator when present. See compile.md §4 emit rules.
228
228
  },
229
229
  // scripts[] and assets[] — include ONLY when inventories are non-empty; omit entirely otherwise
230
230
  // "scripts": [{ "file": "scripts/{name}", "purpose": "{description}", "source_file": "{source-path}", "confidence": "T1-low" }],
@@ -329,12 +329,12 @@ Each reference file includes:
329
329
  |---|---|---|---|---|
330
330
  | `"script"` | `scripts_inventory` | yes → `scripts/` | `"file-copy"` | Runnable scripts (CLI tools, validation scripts, etc.) bundled into the skill for execution. |
331
331
  | `"asset"` | `assets_inventory` | yes → `assets/` | `"file-copy"` | Data files (templates, JSON schemas, config fixtures) bundled for reference. |
332
- | `"doc"` | `promoted_docs` (from step-03 §2a) | **no** | `"promoted-authoritative"` | Authoritative AI documentation files (`llms.txt`, `AGENTS.md`, etc.) promoted into scope by the Discovered Authoritative Files Protocol. The source file is tracked for drift detection but not bundled into the skill — its content influences compile-time decisions (description, Quick Start) and is watched for upstream changes. |
332
+ | `"doc"` | `promoted_docs` (from step 3 §2a) | **no** | `"promoted-authoritative"` | Authoritative AI documentation files (`llms.txt`, `AGENTS.md`, etc.) promoted into scope by the Discovered Authoritative Files Protocol. The source file is tracked for drift detection but not bundled into the skill — its content influences compile-time decisions (description, Quick Start) and is watched for upstream changes. |
333
333
 
334
334
  When `file_type: "doc"`:
335
335
 
336
336
  - `source_file` is the relative path from the source root to the authoritative doc.
337
- - `content_hash` is computed at promotion time (step-03 §2a) and persisted here so update-skill Category D can detect drift via hash comparison.
337
+ - `content_hash` is computed at promotion time (step 3 §2a) and persisted here so update-skill Category D can detect drift via hash comparison.
338
338
  - `file_name` convention: use the source-relative path prefixed with `docs/authoritative/` to namespace doc entries away from script/asset filenames in tools that iterate `file_entries[]` by `file_name`. Example: `docs/authoritative/apps/docs/public/llms.txt`. Step-07 does not write this path — it is a synthetic namespace used only within the provenance map.
339
339
  - `confidence` is `"T1-low"` (the promotion decision is source-level but the content was not AST-parsed).
340
340
 
@@ -392,4 +392,4 @@ t2_future_count: {N}
392
392
 
393
393
  **Frontmatter — pinned detection contract:** the `t2_future_count` field is the authoritative forward-looking-annotation count for downstream gate checks (e.g. skf-test-skill §2b migration-section rule). Emit **always**, even when 0 — omission is indistinguishable from "no T2-future data" and silently flips the gate into Case 2/3 for a Case-1 skill. `generated` and `forge_tier` mirror the narrative header for consumers that read only the frontmatter. Downstream gate rules MUST parse `t2_future_count` from frontmatter, not grep prose — prose drift (heading renames, alternate phrasings like "forward-looking annotations") silently breaks the detection.
394
394
 
395
- **Description Guard slot:** populated by step-06 §0 (create-skill) and §0 (update-skill) when the guard protocol fires. `Restored: true` indicates that an external tool (typically `skill-check --fix` or `split-body`) rewrote the frontmatter `description` and the guard restored the pre-tool value. When `Restored: false`, leave `Triggering tool`, `Original description preserved`, and `Notes` as `—`. When `Restored: true`, fill all four fields: tool name, whether the original was successfully written back, and a one-sentence note describing what the tool had changed (e.g., "replaced with generic summary", "truncated at 80 chars", "angle-bracket tokens re-introduced"). Downstream test-skill assertions can grep for `Restored: true` to detect unintended tool rewrites without parsing free-form warning prose.
395
+ **Description Guard slot:** populated by step 6 §0 (create-skill) and §0 (update-skill) when the guard protocol fires. `Restored: true` indicates that an external tool (typically `skill-check --fix` or `split-body`) rewrote the frontmatter `description` and the guard restored the pre-tool value. When `Restored: false`, leave `Triggering tool`, `Original description preserved`, and `Notes` as `—`. When `Restored: true`, fill all four fields: tool name, whether the original was successfully written back, and a one-sentence note describing what the tool had changed (e.g., "replaced with generic summary", "truncated at 80 chars", "angle-bracket tokens re-introduced"). Downstream test-skill assertions can grep for `Restored: true` to detect unintended tool rewrites without parsing free-form warning prose.
@@ -2,7 +2,7 @@
2
2
 
3
3
  This file is the **single source of truth** for tessl review findings that Skill Forge expects and must dismiss. Step-06 §6 loads this file, parses the `tessl skill review` JSON output, and cross-references each finding against the rules below. Matches are dismissed with their rationale logged to the evidence report; non-matches surface to the user via §6b.
4
4
 
5
- **Why this file exists:** Previously, expected tessl behavior was enumerated as prose in step-06 itself. Each time tessl evolved a scorer or added a new rule, step-06 had to be manually patched and the prose re-read by every execution. This file moves the expected behavior into a structured list with stable rule IDs, rationales, and match criteria — one place to update when tessl changes, one place to audit what SKF expects.
5
+ **Why this file exists:** Previously, expected tessl behavior was enumerated as prose in step 6 itself. Each time tessl evolved a scorer or added a new rule, step 6 had to be manually patched and the prose re-read by every execution. This file moves the expected behavior into a structured list with stable rule IDs, rationales, and match criteria — one place to update when tessl changes, one place to audit what SKF expects.
6
6
 
7
7
  ---
8
8
 
@@ -13,10 +13,10 @@ When parsing tessl output, check these fields against the thresholds below. Viol
13
13
  | Field | Threshold | Severity on violation | Rationale |
14
14
  |---|---|---|---|
15
15
  | `review_score` (overall) | `>= 60` | warn | Two-tier SKF skills trade some conciseness score for progressive disclosure. 60 is the floor below which something is genuinely wrong. |
16
- | `description_score` | `== 100` | **error — recover, then halt** | step-05 §2a unconditionally replaces `<` with `{` and `>` with `}` in the frontmatter description before validation. A score below 100 indicates the sanitizer was bypassed (downstream tool rewrote the description) or a novel tessl rule. Attempt recovery per rule `description-xml-tags-guarded-upstream` (re-apply the §2a substitution in place on the staging SKILL.md frontmatter and re-run tessl). Halt only if recovery fails. |
16
+ | `description_score` | `== 100` | **error — recover, then halt** | step 5 §2a unconditionally replaces `<` with `{` and `>` with `}` in the frontmatter description before validation. A score below 100 indicates the sanitizer was bypassed (downstream tool rewrote the description) or a novel tessl rule. Attempt recovery per rule `description-xml-tags-guarded-upstream` (re-apply the §2a substitution in place on the staging SKILL.md frontmatter and re-run tessl). Halt only if recovery fails. |
17
17
  | `content_score` | `>= 60` | warn | Two-tier design deliberately duplicates key API data across Tier 1 and Tier 2. Conciseness scorer penalizes this. 60 is the acceptable floor. |
18
18
 
19
- If `description_score < 100`, **attempt recovery first** per rule `description-xml-tags-guarded-upstream` below: re-apply step-05 §2a's `<` → `{` / `>` → `}` substitution in place on the staging SKILL.md frontmatter `description`, then re-run `npx -y tessl skill review <staging-skill-dir>` once. If the re-run produces `description_score == 100`, log `description-recovery: applied ({count} substitutions)` in the evidence report and proceed to normal suggestion handling. If recovery fails, halt with: "Description sanitization recovery failed — step-05 §2a's `<`/`>` → `{`/`}` replacement did not resolve the tessl finding. Investigate the staging SKILL.md frontmatter for non-angle-bracket content that tessl is still rejecting, and patch §2a accordingly. Do not edit the description manually." Do NOT proceed to §6b user prompt on an unrecovered failure.
19
+ If `description_score < 100`, **attempt recovery first** per rule `description-xml-tags-guarded-upstream` below: re-apply step 5 §2a's `<` → `{` / `>` → `}` substitution in place on the staging SKILL.md frontmatter `description`, then re-run `npx -y tessl skill review <staging-skill-dir>` once. If the re-run produces `description_score == 100`, log `description-recovery: applied ({count} substitutions)` in the evidence report and proceed to normal suggestion handling. If recovery fails, halt with: "Description sanitization recovery failed — step 5 §2a's `<`/`>` → `{`/`}` replacement did not resolve the tessl finding. Investigate the staging SKILL.md frontmatter for non-angle-bracket content that tessl is still rejecting, and patch §2a accordingly. Do not edit the description manually." Do NOT proceed to §6b user prompt on an unrecovered failure.
20
20
 
21
21
  ---
22
22
 
@@ -39,7 +39,7 @@ Each rule below describes a tessl suggestion that Skill Forge expects and dismis
39
39
  - **Match criteria (all of):**
40
40
  - Suggestion text mentions `Full API Reference` OR a `## Full ...` section heading
41
41
  - Suggestion text contains one of: `move`, `relocate`, `extract`, `split out`, `separate file`, `external file`
42
- - **Rationale:** The two-tier design (Tier 1 inline + Tier 2 inline) keeps Tier 2 sections inline by default. `skill-check split-body` relocates Tier 2 to `references/` only when the body exceeds size limits — see step-06 §4. Preemptive relocation destroys the standalone SKILL.md that the cited 100% task accuracy (vs. 79% for on-demand retrieval) depends on.
42
+ - **Rationale:** The two-tier design (Tier 1 inline + Tier 2 inline) keeps Tier 2 sections inline by default. `skill-check split-body` relocates Tier 2 to `references/` only when the body exceeds size limits — see step 6 §4. Preemptive relocation destroys the standalone SKILL.md that the cited 100% task accuracy (vs. 79% for on-demand retrieval) depends on.
43
43
  - **Action:** dismiss.
44
44
 
45
45
  ### Rule: `consolidate-duplicate-parameters`
@@ -48,7 +48,7 @@ Each rule below describes a tessl suggestion that Skill Forge expects and dismis
48
48
  - **Match criteria (any of):**
49
49
  - Suggestion mentions `duplicate parameter`, `redundant parameter`, `consolidate parameter`
50
50
  - Suggestion mentions both `Key API` / `Key API Summary` AND `Full API Reference` and suggests merging them
51
- - **Rationale:** Tier 1 Key API Summary intentionally lists only key parameters for standalone discoverability. Tier 2 Full API Reference provides complete parameter tables, types, defaults, and edge cases. This is progressive disclosure, not duplication. Consolidating would force agents to scroll to Tier 2 for the most common function calls, defeating Tier 1's purpose and breaking the split-body Tier 1 preservation contract in step-06 §4.
51
+ - **Rationale:** Tier 1 Key API Summary intentionally lists only key parameters for standalone discoverability. Tier 2 Full API Reference provides complete parameter tables, types, defaults, and edge cases. This is progressive disclosure, not duplication. Consolidating would force agents to scroll to Tier 2 for the most common function calls, defeating Tier 1's purpose and breaking the split-body Tier 1 preservation contract in step 6 §4.
52
52
  - **Action:** dismiss.
53
53
 
54
54
  ### Rule: `conciseness-redundancy-between-tiers`
@@ -66,14 +66,14 @@ Each rule below describes a tessl suggestion that Skill Forge expects and dismis
66
66
  - **Scorer:** `description_field` (deterministic validator)
67
67
  - **Match criteria (any of):**
68
68
  - Finding rule ID is `description_field` AND message mentions `XML tag`, `must not contain`, or angle-bracket-related text
69
- - **Expected occurrence:** zero. step-05 §2a unconditionally replaces `<` with `{` and `>` with `}` in the frontmatter description before SKILL.md is written.
70
- - **Action:** **Attempt recovery, then halt if recovery fails.** This is not a dismissal — the finding represents a real sanitizer bypass that step-06 must resolve before proceeding.
69
+ - **Expected occurrence:** zero. step 5 §2a unconditionally replaces `<` with `{` and `>` with `}` in the frontmatter description before SKILL.md is written.
70
+ - **Action:** **Attempt recovery, then halt if recovery fails.** This is not a dismissal — the finding represents a real sanitizer bypass that step 6 must resolve before proceeding.
71
71
  1. **Re-apply §2a in place.** Read the current `description` from the on-disk staging SKILL.md frontmatter, replace every `<` with `{` and every `>` with `}`, and write the result back to the frontmatter. Re-sync the in-context copy to match. Count the substitutions; if zero, the description is already clean and the tessl finding points at something other than angle brackets — skip to the halt branch below.
72
72
  2. **Re-run tessl once.** Execute `npx -y tessl skill review <staging-skill-dir>` a second time and re-parse the JSON output.
73
73
  3. **On success** (`description_score == 100`): log `description-recovery: applied ({count} substitutions)` in the evidence report under "Dismissed tessl suggestions", then continue §6 with the recovered review result (proceed to normal suggestion handling against the rules below). The rerun's `judge_suggestions[]` replaces the original.
74
- 4. **On failure** (`description_score` still < 100 after re-sanitization): halt with: "Description sanitization recovery failed — step-05 §2a's `<`/`>` → `{`/`}` replacement did not resolve the tessl finding. Investigate the staging SKILL.md frontmatter for non-angle-bracket content that tessl is still rejecting, and patch §2a accordingly. Do not edit the description manually."
74
+ 4. **On failure** (`description_score` still < 100 after re-sanitization): halt with: "Description sanitization recovery failed — step 5 §2a's `<`/`>` → `{`/`}` replacement did not resolve the tessl finding. Investigate the staging SKILL.md frontmatter for non-angle-bracket content that tessl is still rejecting, and patch §2a accordingly. Do not edit the description manually."
75
75
 
76
- The recovery path makes the skill shippable when a downstream tool (`skill-check --fix`, `split-body`, or a future validator) re-introduces angle brackets into the description after §2a has run. The Description Guard Protocol in step-06 §0 is the first line of defense against such rewrites; this rule is the second line, active when the guard also missed.
76
+ The recovery path makes the skill shippable when a downstream tool (`skill-check --fix`, `split-body`, or a future validator) re-introduces angle brackets into the description after §2a has run. The Description Guard Protocol in step 6 §0 is the first line of defense against such rewrites; this rule is the second line, active when the guard also missed.
77
77
 
78
78
  ---
79
79
 
@@ -97,6 +97,6 @@ When tessl introduces new rules, changes scorer behavior, or SKF design decision
97
97
  1. **Add a new rule section** above with `Rule:`, `Scorer:`, `Match criteria`, `Rationale`, `Action`.
98
98
  2. **Link the rationale** to the concrete SKF design principle it protects (two-tier design, MANUAL markers, sanitization, split-body preservation, etc.). A rationale without a design-principle link is a smell.
99
99
  3. **Keep score thresholds above current production floors.** Do not lower them to suppress real regressions.
100
- 4. **Never embed dismissal logic in step files.** If step-06 needs updated behavior, update this file first and reference it from step-06.
100
+ 4. **Never embed dismissal logic in step files.** If step 6 needs updated behavior, update this file first and reference it from step 6.
101
101
 
102
- This file is load-bearing: step-06 §6 has no other source of truth for expected tessl behavior.
102
+ This file is load-bearing: step 6 §6 has no other source of truth for expected tessl behavior.
@@ -0,0 +1,35 @@
1
+ # DO NOT EDIT -- overwritten on every update.
2
+ #
3
+ # Workflow customization surface for skf-create-skill.
4
+
5
+ [workflow]
6
+
7
+ # --- Configurable below. Overrides merge per BMad structural rules: ---
8
+ # scalars: override wins • arrays (persistent_facts, activation_steps_*): append
9
+ # arrays-of-tables with `code`/`id`: replace matching items, append new ones.
10
+
11
+ # Steps to run before the standard activation (uv probe, config load).
12
+ # Overrides append. Use for org-wide pre-flight checks (auth, network,
13
+ # compliance) that must precede any skill compilation work.
14
+
15
+ activation_steps_prepend = []
16
+
17
+ # Steps to run after activation but before the first stage executes.
18
+ # Overrides append. Use for context loads or banner customization that
19
+ # should run once activation completes successfully.
20
+
21
+ activation_steps_append = []
22
+
23
+ # Persistent facts the workflow keeps in mind for the whole run
24
+ # (extraction style, compilation guardrails, tessl review preferences).
25
+ # Overrides append.
26
+ #
27
+ # Each entry is either:
28
+ # - a literal sentence, e.g. "Skills must declare PEP 723 inline metadata."
29
+ # - a file reference prefixed with `file:`, e.g.
30
+ # "file:{project-root}/docs/create-policy.md" (globs supported; file
31
+ # contents are loaded and treated as facts).
32
+
33
+ persistent_facts = [
34
+ "file:{project-root}/**/project-context.md",
35
+ ]
@@ -0,0 +1,142 @@
1
+ # Authoritative Files Protocol
2
+
3
+ ## Overview
4
+
5
+ Carved from `extract.md §2a`. Loaded on demand when step 3's `### 2a. Discovered Authoritative Files Protocol` sub-step runs.
6
+
7
+ **Skip this protocol entirely if `source_type: "docs-only"`** — there is no source tree to scan.
8
+
9
+ Before resolving source access for extraction, scan the source tree for **authoritative AI documentation files** that the brief's scope filters excluded. Project authors increasingly add files specifically written to steer AI assistants (`llms.txt`, `AGENTS.md`, `.cursorrules`, etc.), and these files often contain the **canonical** install command, quick-start, or architecture summary — information that nowhere else in the source tree provides. A brief authored from a scan of `src/**` will frequently exclude these files without the author realizing they exist.
10
+
11
+ This protocol detects such files, prompts the user, and records the decision in the brief so future runs (re-create, update, audit) honor it.
12
+
13
+ **Heuristic scan list (handled by the helper — listed here for reference):** case-insensitive basename match, any directory depth, on `llms.txt`, `llms-full.txt`, `AGENTS.md`, `CLAUDE.md`, `GEMINI.md`, `COPILOT.md`, `.cursorrules`, `.windsurfrules`, `.clinerules`.
14
+
15
+ ## Procedure
16
+
17
+ 1. **Resolve, scan, classify, and load previews in one call.** The helper handles the source-tree walk (pruning `node_modules`, `dist`, `.git`, etc.), case-insensitive basename matching, scope-filter diff (with `**`-recursive-glob support), amendment reconciliation (most-recent action wins), preview load (first 20 lines), and SHA-256 hashing:
18
+
19
+ ```bash
20
+ uv run {resolveAuthoritativeFilesHelper} resolve \
21
+ --source-root {source_root} \
22
+ --brief {forge_data_folder}/{skill_name}/skill-brief.yaml \
23
+ [--preview-lines 20]
24
+ ```
25
+
26
+ The helper emits one envelope with three buckets:
27
+
28
+ ```json
29
+ {
30
+ "status": "no-candidates" | "candidates-found",
31
+ "summary": {
32
+ "candidates_total": N, "already_in_scope_count": N,
33
+ "pre_decided_count": N, "unresolved_count": N
34
+ },
35
+ "already_in_scope": [
36
+ {"path": "...", "heuristic": "...", "size_bytes": N,
37
+ "line_count": N, "content_hash": "sha256:..."}
38
+ ],
39
+ "pre_decided": [
40
+ {"path": "...", "heuristic": "...",
41
+ "prior_action": "promoted"|"skipped",
42
+ "should_add_to_promoted_docs": <bool>,
43
+ "size_bytes": N|null, "line_count": N|null,
44
+ "content_hash": "sha256:..."|null}
45
+ ],
46
+ "unresolved": [
47
+ {"path": "...", "heuristic": "...", "size_bytes": N,
48
+ "line_count": N, "content_hash": "sha256:...",
49
+ "preview": "<first N lines>",
50
+ "excluded_by_pattern": "<glob>"|"not matched by any scope.include"}
51
+ ]
52
+ }
53
+ ```
54
+
55
+ 2. **Apply the helper's classification:**
56
+
57
+ - **`already_in_scope[]`** — file is in scope and not skipped. **Remove the path from §2's filtered file list** and append the record to in-context `promoted_docs[]`. No prompt — authoritative docs must never reach §4 code extraction even when scope.include matches.
58
+ - **`pre_decided[]` with `prior_action: "promoted"`** — amendment says promoted; **append to `promoted_docs[]`** using the helper-supplied hash/size/lines. Deterministic replay path.
59
+ - **`pre_decided[]` with `prior_action: "skipped"`** — user previously declined. Do nothing. Move on.
60
+ - **`unresolved[]`** — proceed to step 3 below (user prompt).
61
+
62
+ 3. **Prompt.** Present each `unresolved[]` candidate to the user. Use the helper's `preview`, `size_bytes`, `line_count`, and `excluded_by_pattern` fields verbatim — they replace what the LLM previously had to compute itself:
63
+
64
+ ```
65
+ **Discovered authoritative file excluded by brief scope**
66
+
67
+ Path: {relative_path_from_source_root}
68
+ Size: {line_count} lines, {bytes} bytes
69
+ Matched heuristic: {basename}
70
+ Excluded by pattern: {matching_exclude_pattern or "not matched by any scope.include"}
71
+
72
+ First 20 lines:
73
+ {inline preview}
74
+
75
+ This file is typically authored for AI assistants and may contain canonical usage information not present elsewhere in the source. How should extraction handle it?
76
+
77
+ [P] Promote — include in this extraction run AND amend brief for future runs
78
+ [S] Skip — honor the brief exclusion AND record skip in amendments (no re-prompt)
79
+ [U] Update — halt this run and return to skf-brief-skill to refine scope
80
+ ```
81
+
82
+ 4. **Headless mode (`{headless_mode}` is true):** auto-select `[S] Skip` for every candidate. Record amendment entries with `action: "skipped"` and `reason: "headless: no user to prompt"`. A non-interactive run must never silently promote files into scope — the decision requires a human.
83
+
84
+ 5. **Apply decision:**
85
+
86
+ - **[P] Promote:**
87
+ 1. **Do NOT add the path to the filtered file list from §2.** Authoritative documentation files are not code — they must not go through the AST extraction pipeline in §4, which would silently produce no exports (ghost entries). Instead, add the path to a new in-context list `promoted_docs[]` with `{path, heuristic, size_bytes, line_count, content_hash}`. Compute the SHA-256 content hash of the file now.
88
+ 2. Append to `brief.scope.include`: add the exact `candidate.path` as a literal glob (no wildcards — the amendment targets this specific file). This write ensures that a re-run of `skf-create-skill` against the amended brief sees the path in scope and skips re-prompting.
89
+ 3. Append to `brief.scope.amendments[]` a new entry with `action: "promoted"`, `path: candidate.path`, `reason: {user-provided one-sentence reason or auto-generated "authoritative AI docs — matched heuristic {basename}"}`, `heuristic: {basename}`, `date: {today ISO}`, `workflow: "skf-create-skill"`.
90
+ 4. **Write the amended brief back to disk immediately** at `{forge_data_folder}/{skill_name}/skill-brief.yaml`. Immediate write (not deferred to step 7) ensures a crashed run still leaves the amendment recorded. Preserve all other brief fields and formatting. **Use atomic write + backup:** before writing, copy the original brief to `{forge_data_folder}/{skill_name}/skill-brief.yaml.bak` (overwriting any prior `.bak` — the most recent pre-amendment snapshot is the useful one). Then pipe the amended YAML through the shared atomic writer so a crash mid-write cannot corrupt the brief:
91
+
92
+ ```bash
93
+ # 1. Backup
94
+ cp {forge_data_folder}/{skill_name}/skill-brief.yaml \
95
+ {forge_data_folder}/{skill_name}/skill-brief.yaml.bak
96
+
97
+ # 2. Atomic write (stdin → tmp → fsync → rename)
98
+ cat <<'AMENDED_YAML' | python3 {atomicWriteHelper} write \
99
+ --target {forge_data_folder}/{skill_name}/skill-brief.yaml
100
+ {amended brief YAML}
101
+ AMENDED_YAML
102
+ ```
103
+
104
+ The helper stages into `{brief}.skf-tmp`, fsyncs, then `os.replace()`s — readers never see a half-written brief.
105
+ 5. Display: "**Promoted `{path}`** — tracked as documentation file, amendment recorded."
106
+
107
+ - **[S] Skip:**
108
+ 1. Do NOT modify `scope.include` or `scope.exclude`.
109
+ 2. Append to `brief.scope.amendments[]` a new entry with `action: "skipped"`, `path: candidate.path`, `reason: {user-provided reason or auto-generated "user declined promotion at create-skill §2a"}`, `heuristic: {basename}`, `date: {today ISO}`, `workflow: "skf-create-skill"`.
110
+ 3. **Write the amended brief back to disk** so future runs do not re-prompt. Use the same backup-then-atomic-write pattern as the [P] Promote path (copy to `skill-brief.yaml.bak` first, then pipe through `skf-atomic-write.py write --target {brief_path}`).
111
+ 4. Display: "**Skipped `{path}`** — decision recorded in amendments."
112
+
113
+ - **[U] Update:**
114
+ 1. Halt the workflow immediately.
115
+ 2. Display: "**Halting create-skill.** Re-run `skf-brief-skill` to refine the scope filters for `{skill_name}`, then re-run `skf-create-skill`. Decisions for previously prompted candidates were already persisted to the brief; the current candidate was not written."
116
+ 3. Exit with status `halted-for-brief-refinement`.
117
+
118
+ 6. **Summary.** After all candidates are resolved (or none were found), display a one-line summary:
119
+
120
+ - `"Authoritative files scan: {N} candidates, {P} promoted, {S} skipped, {A} pre-decided from amendments."`
121
+ - If N = 0: `"Authoritative files scan: no candidates."`
122
+
123
+ **Record for evidence report:** `authoritative_files_scan: {candidates: N, promoted: P, skipped: S, pre_decided: A, decisions: [{path, action, heuristic, reason}]}` — step 7 includes this in `evidence-report.md`.
124
+
125
+ ## How promoted docs reach the provenance map
126
+
127
+ Promoted docs do NOT flow through §4 code extraction. Instead:
128
+
129
+ 1. §2a populates the in-context `promoted_docs[]` list with content hashes.
130
+ 2. **Step-05 §6** (provenance-map assembly) reads `promoted_docs[]` and emits one `file_entries[]` entry per promoted doc with `file_type: "doc"`, `extraction_method: "promoted-authoritative"`, `confidence: "T1-low"`, and the pre-computed `content_hash`.
131
+ 3. **Step-07 §2** does NOT copy doc files into the skill package (unlike scripts and assets). The source file remains at its original path; only the provenance map tracks it. Future audit and update workflows compare against this tracking entry via content hash — no file copy is required because the intent is drift detection on the *source*, not bundling documentation into the skill output.
132
+
133
+ **Re-running `skf-create-skill`** reads the amended brief. Files with `action: "promoted"` amendments already appear in `scope.include`, but §2a still runs — it detects the file is in scope AND has an existing amendment, and takes the "pre-decided" silent path. The `promoted_docs[]` list is rebuilt on each run by scanning amendments with `action: "promoted"` (this is the deterministic replay path).
134
+
135
+ ## Downstream workflow consumption
136
+
137
+ Zero code changes required in consumer workflows:
138
+
139
+ - **`skf-update-skill`** reads `provenance-map.json`. Promoted docs appear as `file_entries[]` entries. Update-skill Category D (script/asset file changes) iterates `file_entries` and compares content hashes — this works identically for `file_type: "doc"` entries, giving drift detection for free.
140
+ - **`skf-audit-skill`** (after the bounded re-index fix) scans files from `provenance-map.json`. The re-index builds its list from `entries[].source_file ∪ file_entries[].source_file`, so promoted doc paths are naturally included in the audit scan.
141
+
142
+ The brief is the single source of truth for authored scope intent. The provenance map is the single source of truth for extracted state. `scope.amendments[]` is the bridge that records when those two intentionally diverged. `promoted_docs[]` is the in-memory handoff from §2a to step 5 §6; it is not persisted — the persisted form is the `file_entries[]` list in provenance-map.json.