bmad-module-skill-forge 1.4.1 → 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.
- package/.claude-plugin/marketplace.json +1 -1
- package/README.md +0 -8
- package/docs/_data/pinned.yaml +1 -1
- package/docs/_internal/STABILITY.md +1 -1
- package/docs/architecture.md +2 -2
- package/docs/examples.md +1 -1
- package/docs/workflows.md +5 -5
- package/package.json +2 -2
- package/src/README.md +1 -1
- package/src/knowledge/ccc-bridge.md +12 -12
- package/src/knowledge/qmd-registry.md +5 -5
- package/src/shared/health-check.md +5 -5
- package/src/shared/references/description-guard-protocol.md +100 -0
- package/src/shared/references/output-contract-schema.md +1 -1
- package/src/shared/scripts/schemas/skf-brief-result-envelope.v1.json +6 -6
- package/src/shared/scripts/schemas/skf-setup-result-envelope.v1.json +9 -3
- package/src/shared/scripts/schemas/skf-update-result-envelope.v1.json +149 -0
- package/src/shared/scripts/schemas/skill-brief.v1.json +22 -2
- package/src/shared/scripts/skf-build-change-manifest.py +420 -0
- package/src/shared/scripts/skf-check-workspace-drift.py +321 -0
- package/src/shared/scripts/skf-compare-file-hashes.py +357 -0
- package/src/shared/scripts/skf-description-guard.py +359 -0
- package/src/shared/scripts/skf-detect-language.py +2 -2
- package/src/shared/scripts/skf-detect-scripts-assets.py +613 -0
- package/src/shared/scripts/skf-detect-tools.py +97 -8
- package/src/shared/scripts/skf-detect-workspaces.py +1 -1
- package/src/shared/scripts/skf-disqualify-candidates.py +576 -0
- package/src/shared/scripts/skf-emit-brief-result-envelope.py +3 -3
- package/src/shared/scripts/skf-emit-result-envelope.py +93 -9
- package/src/shared/scripts/skf-enumerate-stack-skills.py +514 -0
- package/src/shared/scripts/skf-forge-tier-rw.py +11 -11
- package/src/shared/scripts/skf-hash-content.py +284 -0
- package/src/shared/scripts/skf-load-provenance.py +295 -0
- package/src/shared/scripts/skf-merge-ccc-exclusions.py +34 -4
- package/src/shared/scripts/skf-pair-intersect.py +250 -0
- package/src/shared/scripts/skf-provenance-gap-dispatch.py +433 -0
- package/src/shared/scripts/skf-qmd-classify-collections.py +42 -8
- package/src/shared/scripts/skf-recommend-scope-type.py +2 -2
- package/src/shared/scripts/skf-render-quick-metadata.py +2 -2
- package/src/shared/scripts/skf-resolve-authoritative-files.py +504 -0
- package/src/shared/scripts/skf-scan-manifests.py +738 -0
- package/src/shared/scripts/skf-scan-skill-md-structure.py +375 -0
- package/src/shared/scripts/skf-update-active-symlink.py +315 -0
- package/src/shared/scripts/skf-validate-brief-inputs.py +5 -5
- package/src/shared/scripts/skf-validate-brief-schema.py +348 -0
- package/src/shared/scripts/skf-write-skill-brief.py +61 -5
- package/src/skf-analyze-source/SKILL.md +69 -16
- package/src/skf-analyze-source/assets/skill-brief-schema.md +1 -1
- package/src/skf-analyze-source/customize.toml +55 -0
- package/src/skf-analyze-source/{steps-c/step-01b-continue.md → references/continue.md} +12 -12
- package/src/skf-analyze-source/{steps-c/step-06-generate-briefs.md → references/generate-briefs.md} +29 -10
- package/src/skf-analyze-source/{steps-c/step-07-health-check.md → references/health-check.md} +5 -3
- package/src/skf-analyze-source/{steps-c/step-03-identify-units.md → references/identify-units.md} +44 -14
- package/src/skf-analyze-source/{steps-c/step-01-init.md → references/init.md} +27 -6
- package/src/skf-analyze-source/{steps-c/step-04-map-and-detect.md → references/map-and-detect.md} +52 -25
- package/src/skf-analyze-source/{steps-c/step-05-recommend.md → references/recommend.md} +15 -8
- package/src/skf-analyze-source/{steps-c/step-02-scan-project.md → references/scan-project.md} +12 -10
- package/src/skf-analyze-source/references/unit-detection-heuristics.md +2 -0
- package/src/skf-analyze-source/templates/analysis-report-template.md +6 -6
- package/src/skf-audit-skill/SKILL.md +66 -15
- package/src/skf-audit-skill/assets/drift-report-template.md +6 -5
- package/src/skf-audit-skill/customize.toml +49 -0
- package/src/skf-audit-skill/{steps-c/step-07-health-check.md → references/health-check.md} +5 -3
- package/src/skf-audit-skill/{steps-c/step-01-init.md → references/init.md} +57 -19
- package/src/skf-audit-skill/{steps-c/step-02-re-index.md → references/re-index.md} +11 -11
- package/src/skf-audit-skill/{steps-c/step-06-report.md → references/report.md} +25 -7
- package/src/skf-audit-skill/{steps-c/step-04-semantic-diff.md → references/semantic-diff.md} +6 -6
- package/src/skf-audit-skill/{steps-c/step-05-severity-classify.md → references/severity-classify.md} +5 -5
- package/src/skf-audit-skill/references/severity-rules.md +2 -0
- package/src/skf-audit-skill/{steps-c/step-03-structural-diff.md → references/structural-diff.md} +29 -17
- package/src/skf-brief-skill/SKILL.md +48 -18
- package/src/skf-brief-skill/assets/description-voice-examples.md +1 -1
- package/src/skf-brief-skill/assets/skill-brief-schema.md +32 -2
- package/src/skf-brief-skill/customize.toml +44 -0
- package/src/skf-brief-skill/{steps-c/step-02-analyze-target.md → references/analyze-target.md} +5 -5
- package/src/skf-brief-skill/{steps-c/step-04-confirm-brief.md → references/confirm-brief.md} +13 -10
- package/src/skf-brief-skill/references/draft-checkpoint.md +4 -4
- package/src/skf-brief-skill/{steps-c/step-01-gather-intent.md → references/gather-intent.md} +24 -24
- package/src/skf-brief-skill/references/headless-args.md +9 -9
- package/src/skf-brief-skill/references/headless-source-authority-detection.md +1 -1
- package/src/skf-brief-skill/{steps-c/step-06-health-check.md → references/health-check.md} +4 -2
- package/src/skf-brief-skill/references/portfolio-similarity-check.md +2 -2
- package/src/skf-brief-skill/references/qmd-collection-registration.md +1 -1
- package/src/skf-brief-skill/{steps-c/step-03-scope-definition.md → references/scope-definition.md} +19 -16
- package/src/skf-brief-skill/references/version-resolution.md +2 -2
- package/src/skf-brief-skill/{steps-c/step-05-write-brief.md → references/write-brief.md} +11 -10
- package/src/skf-create-skill/SKILL.md +25 -19
- package/src/skf-create-skill/assets/compile-assembly-rules.md +3 -3
- package/src/skf-create-skill/assets/skill-sections.md +5 -5
- package/src/skf-create-skill/assets/tessl-dismissal-rules.md +11 -11
- package/src/skf-create-skill/customize.toml +35 -0
- package/src/skf-create-skill/references/authoritative-files-protocol.md +142 -0
- package/src/skf-create-skill/{steps-c/step-05-compile.md → references/compile.md} +16 -16
- package/src/skf-create-skill/{steps-c/step-03d-component-extraction.md → references/component-extraction.md} +16 -16
- package/src/skf-create-skill/{steps-c/step-02-ecosystem-check.md → references/ecosystem-check.md} +4 -4
- package/src/skf-create-skill/{steps-c/step-04-enrich.md → references/enrich.md} +3 -3
- package/src/skf-create-skill/{steps-c/step-03-extract.md → references/extract.md} +52 -120
- package/src/skf-create-skill/references/extraction-patterns.md +8 -8
- package/src/skf-create-skill/{steps-c/step-07-generate-artifacts.md → references/generate-artifacts.md} +11 -11
- package/src/skf-create-skill/{steps-c/step-09-health-check.md → references/health-check.md} +4 -2
- package/src/skf-create-skill/{steps-c/step-01-load-brief.md → references/load-brief.md} +40 -32
- package/src/skf-create-skill/{steps-c/step-08-report.md → references/report.md} +8 -8
- package/src/skf-create-skill/references/source-resolution-protocols.md +6 -6
- package/src/skf-create-skill/{steps-c/sub/step-02b-ccc-discover.md → references/sub/ccc-discover.md} +5 -5
- package/src/skf-create-skill/{steps-c/sub/step-03c-fetch-docs.md → references/sub/fetch-docs.md} +28 -12
- package/src/skf-create-skill/{steps-c/sub/step-03b-fetch-temporal.md → references/sub/fetch-temporal.md} +81 -50
- package/src/skf-create-skill/{steps-c/step-06-validate.md → references/validate.md} +46 -26
- package/src/skf-create-stack-skill/SKILL.md +76 -17
- package/src/skf-create-stack-skill/assets/provenance-map-schema.md +102 -0
- package/src/skf-create-stack-skill/assets/stack-skill-template.md +1 -1
- package/src/skf-create-stack-skill/customize.toml +46 -0
- package/src/skf-create-stack-skill/{steps-c/step-06-compile-stack.md → references/compile-stack.md} +6 -5
- package/src/skf-create-stack-skill/references/compose-mode-rules.md +3 -1
- package/src/skf-create-stack-skill/{steps-c/step-05-detect-integrations.md → references/detect-integrations.md} +32 -11
- package/src/skf-create-stack-skill/{steps-c/step-02-detect-manifests.md → references/detect-manifests.md} +28 -28
- package/src/skf-create-stack-skill/{steps-c/step-07-generate-output.md → references/generate-output.md} +11 -85
- package/src/skf-create-stack-skill/{steps-c/step-10-health-check.md → references/health-check.md} +4 -2
- package/src/skf-create-stack-skill/{steps-c/step-01-init.md → references/init.md} +70 -4
- package/src/skf-create-stack-skill/references/integration-patterns.md +2 -0
- package/src/skf-create-stack-skill/references/manifest-patterns.md +2 -0
- package/src/skf-create-stack-skill/{steps-c/step-04-parallel-extract.md → references/parallel-extract.md} +40 -17
- package/src/skf-create-stack-skill/{steps-c/step-03-rank-and-confirm.md → references/rank-and-confirm.md} +5 -4
- package/src/skf-create-stack-skill/{steps-c/step-09-report.md → references/report.md} +3 -3
- package/src/skf-create-stack-skill/{steps-c/step-08-validate.md → references/validate.md} +6 -6
- package/src/skf-drop-skill/SKILL.md +84 -12
- package/src/skf-drop-skill/customize.toml +57 -0
- package/src/skf-drop-skill/{steps-c/step-02-execute.md → references/execute.md} +49 -34
- package/src/skf-drop-skill/{steps-c/step-04-health-check.md → references/health-check.md} +6 -4
- package/src/skf-drop-skill/{steps-c/step-03-report.md → references/report.md} +13 -5
- package/src/skf-drop-skill/{steps-c/step-01-select.md → references/select.md} +63 -15
- package/src/skf-export-skill/SKILL.md +85 -16
- package/src/skf-export-skill/assets/managed-section-format.md +3 -3
- package/src/skf-export-skill/assets/snippet-format.md +2 -2
- package/src/skf-export-skill/customize.toml +49 -0
- package/src/skf-export-skill/{steps-c/step-03-generate-snippet.md → references/generate-snippet.md} +11 -11
- package/src/skf-export-skill/{steps-c/step-07-health-check.md → references/health-check.md} +6 -4
- package/src/skf-export-skill/{steps-c/step-01-load-skill.md → references/load-skill.md} +11 -49
- package/src/skf-export-skill/references/manifest-rebuild.md +68 -0
- package/src/skf-export-skill/references/multi-skill-mode.md +38 -0
- package/src/skf-export-skill/references/orphan-context-detection.md +75 -0
- package/src/skf-export-skill/references/orphan-row-detection.md +102 -0
- package/src/skf-export-skill/{steps-c/step-02-package.md → references/package.md} +7 -7
- package/src/skf-export-skill/references/preflight-snippet-root-probe.md +74 -0
- package/src/skf-export-skill/{steps-c/step-06-summary.md → references/summary.md} +20 -8
- package/src/skf-export-skill/{steps-c/step-05-token-report.md → references/token-report.md} +5 -5
- package/src/skf-export-skill/{steps-c/step-04-update-context.md → references/update-context.md} +109 -113
- package/src/skf-quick-skill/SKILL.md +63 -123
- package/src/skf-quick-skill/customize.toml +44 -0
- package/src/skf-quick-skill/references/batch-mode.md +102 -0
- package/src/skf-quick-skill/{steps-c/step-04-compile.md → references/compile.md} +10 -10
- package/src/skf-quick-skill/{steps-c/step-02-ecosystem-check.md → references/ecosystem-check.md} +5 -5
- package/src/skf-quick-skill/{steps-c/step-06-finalize.md → references/finalize.md} +7 -7
- package/src/skf-quick-skill/{steps-c/step-07-health-check.md → references/health-check.md} +3 -3
- package/src/skf-quick-skill/{steps-c/step-03-quick-extract.md → references/quick-extract.md} +5 -5
- package/src/skf-quick-skill/references/registry-resolution.md +2 -0
- package/src/skf-quick-skill/{steps-c/step-01-resolve-target.md → references/resolve-target.md} +14 -10
- package/src/skf-quick-skill/{steps-c/step-05-write-and-validate.md → references/write-and-validate.md} +4 -4
- package/src/skf-refine-architecture/SKILL.md +86 -16
- package/src/skf-refine-architecture/customize.toml +49 -0
- package/src/skf-refine-architecture/{steps-c/step-05-compile.md → references/compile.md} +4 -4
- package/src/skf-refine-architecture/{steps-c/step-02-gap-analysis.md → references/gap-analysis.md} +5 -5
- package/src/skf-refine-architecture/{steps-c/step-07-health-check.md → references/health-check.md} +6 -4
- package/src/skf-refine-architecture/{steps-c/step-04-improvements.md → references/improvements.md} +5 -5
- package/src/skf-refine-architecture/references/init.md +144 -0
- package/src/skf-refine-architecture/{steps-c/step-03-issue-detection.md → references/issue-detection.md} +5 -5
- package/src/skf-refine-architecture/references/refinement-rules.md +2 -0
- package/src/skf-refine-architecture/{steps-c/step-06-report.md → references/report.md} +14 -5
- package/src/skf-rename-skill/SKILL.md +82 -12
- package/src/skf-rename-skill/customize.toml +52 -0
- package/src/skf-rename-skill/{steps-c/step-02-execute.md → references/execute.md} +94 -99
- package/src/skf-rename-skill/references/health-check.md +30 -0
- package/src/skf-rename-skill/references/rebuild-context.md +110 -0
- package/src/skf-rename-skill/{steps-c/step-03-report.md → references/report.md} +13 -5
- package/src/skf-rename-skill/{steps-c/step-01-select.md → references/select.md} +59 -20
- package/src/skf-setup/SKILL.md +35 -35
- package/src/skf-setup/customize.toml +33 -0
- package/src/skf-setup/{steps-c/step-03-auto-index.md → references/auto-index.md} +10 -18
- package/src/skf-setup/{steps-c/step-01b-ccc-index.md → references/ccc-index.md} +16 -31
- package/src/skf-setup/{steps-c/step-01-detect-and-tier.md → references/detect-and-tier.md} +23 -10
- package/src/skf-setup/{steps-c/step-05-health-check.md → references/health-check.md} +1 -1
- package/src/skf-setup/{steps-c/step-04-report.md → references/report.md} +21 -19
- package/src/skf-setup/references/tier-rules.md +1 -1
- package/src/skf-setup/{steps-c/step-02-write-config.md → references/write-config.md} +14 -13
- package/src/skf-test-skill/SKILL.md +77 -15
- package/src/skf-test-skill/customize.toml +54 -0
- package/src/skf-test-skill/{steps-c/step-04-coherence-check.md → references/coherence-check.md} +28 -71
- package/src/skf-test-skill/{steps-c/step-03-coverage-check.md → references/coverage-check.md} +16 -39
- package/src/skf-test-skill/{steps-c/step-02-detect-mode.md → references/detect-mode.md} +4 -26
- package/src/skf-test-skill/{steps-c/step-04b-external-validators.md → references/external-validators.md} +6 -28
- package/src/skf-test-skill/references/health-check.md +14 -0
- package/src/skf-test-skill/{steps-c/step-01-init.md → references/init.md} +21 -37
- package/src/skf-test-skill/references/migration-section-rules.md +4 -2
- package/src/skf-test-skill/{steps-c/step-06-report.md → references/report.md} +41 -51
- package/src/skf-test-skill/{steps-c/step-05-score.md → references/score.md} +26 -43
- package/src/skf-test-skill/references/scoring-rules.md +8 -6
- package/src/skf-test-skill/references/source-access-protocol.md +7 -5
- package/src/skf-test-skill/scripts/compute-score.py +88 -17
- package/src/skf-test-skill/templates/test-report-template.md +13 -13
- package/src/skf-update-skill/SKILL.md +23 -14
- package/src/skf-update-skill/customize.toml +44 -0
- package/src/skf-update-skill/{steps-c/step-02-detect-changes.md → references/detect-changes.md} +176 -68
- package/src/skf-update-skill/references/health-check.md +32 -0
- package/src/skf-update-skill/{steps-c/step-01-init.md → references/init.md} +56 -8
- package/src/skf-update-skill/references/manual-section-rules.md +4 -0
- package/src/skf-update-skill/references/merge-conflict-rules.md +4 -0
- package/src/skf-update-skill/{steps-c/step-04-merge.md → references/merge.md} +8 -8
- package/src/skf-update-skill/{steps-c/step-03-re-extract.md → references/re-extract.md} +53 -44
- package/src/skf-update-skill/references/remote-source-resolution.md +5 -1
- package/src/skf-update-skill/references/report.md +214 -0
- package/src/skf-update-skill/{steps-c/step-05-validate.md → references/validate.md} +5 -5
- package/src/skf-update-skill/{steps-c/step-06-write.md → references/write.md} +73 -51
- package/src/skf-verify-stack/SKILL.md +89 -17
- package/src/skf-verify-stack/assets/feasibility-report-template.md +4 -4
- package/src/skf-verify-stack/customize.toml +50 -0
- package/src/skf-verify-stack/references/coverage-patterns.md +2 -2
- package/src/skf-verify-stack/{steps-c/step-02-coverage.md → references/coverage.md} +7 -7
- package/src/skf-verify-stack/{steps-c/step-07-health-check.md → references/health-check.md} +7 -5
- package/src/skf-verify-stack/references/init.md +166 -0
- package/src/skf-verify-stack/references/integration-verification-rules.md +1 -1
- package/src/skf-verify-stack/{steps-c/step-03-integrations.md → references/integrations.md} +12 -12
- package/src/skf-verify-stack/{steps-c/step-06-report.md → references/report.md} +22 -41
- package/src/skf-verify-stack/{steps-c/step-04-requirements.md → references/requirements.md} +7 -7
- package/src/skf-verify-stack/{steps-c/step-05-synthesize.md → references/synthesize.md} +8 -8
- package/tools/validate-docs-drift.js +1 -1
- package/src/skf-refine-architecture/steps-c/step-01-init.md +0 -136
- package/src/skf-rename-skill/steps-c/step-04-health-check.md +0 -22
- package/src/skf-test-skill/steps-c/step-07-health-check.md +0 -25
- package/src/skf-update-skill/steps-c/step-07-report.md +0 -148
- package/src/skf-update-skill/steps-c/step-08-health-check.md +0 -22
- package/src/skf-verify-stack/steps-c/step-01-init.md +0 -178
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
outputFile: '{forge_version}/drift-report-{timestamp}.md'
|
|
3
|
-
nextStepFile: '
|
|
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
|
|
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/
|
|
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
|
|
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 `'
|
|
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.
|
package/src/skf-audit-skill/{steps-c/step-04-semantic-diff.md → references/semantic-diff.md}
RENAMED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
---
|
|
2
|
-
nextStepFile: '
|
|
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 `'
|
|
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
|
|
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 `'
|
|
131
|
+
- Append `'semantic-diff'` to `stepsCompleted`
|
|
132
132
|
|
|
133
133
|
### 6. Present MENU OPTIONS
|
|
134
134
|
|
package/src/skf-audit-skill/{steps-c/step-05-severity-classify.md → references/severity-classify.md}
RENAMED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
---
|
|
2
|
-
nextStepFile: '
|
|
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
|
|
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 `'
|
|
141
|
+
- Append `'severity-classify'` to `stepsCompleted`
|
|
142
142
|
- Set `drift_score` to calculated overall score
|
|
143
143
|
|
|
144
144
|
### 7. Present MENU OPTIONS
|
package/src/skf-audit-skill/{steps-c/step-03-structural-diff.md → references/structural-diff.md}
RENAMED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
---
|
|
2
|
-
nextStepFile: '
|
|
2
|
+
nextStepFile: 'semantic-diff.md'
|
|
3
3
|
outputFile: '{forge_version}/drift-report-{timestamp}.md'
|
|
4
|
+
loadProvenanceScript: '{project-root}/src/shared/scripts/skf-load-provenance.py'
|
|
5
|
+
compareFileHashesScript: '{project-root}/src/shared/scripts/skf-compare-file-hashes.py'
|
|
4
6
|
---
|
|
5
7
|
|
|
8
|
+
<!-- Config: communicate in {communication_language}. -->
|
|
9
|
+
|
|
6
10
|
# Step 3: Structural Diff
|
|
7
11
|
|
|
8
12
|
## STEP GOAL:
|
|
@@ -17,8 +21,6 @@ Compare the original provenance map extractions from create-skill against the cu
|
|
|
17
21
|
|
|
18
22
|
## MANDATORY SEQUENCE
|
|
19
23
|
|
|
20
|
-
**CRITICAL:** Follow this sequence exactly. Do not skip, reorder, or improvise unless user explicitly requests a change.
|
|
21
|
-
|
|
22
24
|
### 1. Prepare Comparison Sets
|
|
23
25
|
|
|
24
26
|
Load both datasets:
|
|
@@ -29,19 +31,19 @@ Load both datasets:
|
|
|
29
31
|
**Current (from Step 02 extraction):**
|
|
30
32
|
- Export list with names, types, signatures, file paths, line numbers
|
|
31
33
|
|
|
32
|
-
**Canonicalize extractor methodology differences before matching.** The extractor used by `skf-create-skill` at baseline time and the re-extractor used by step
|
|
34
|
+
**Canonicalize extractor methodology differences before matching.** The extractor used by `skf-create-skill` at baseline time and the re-extractor used by step 2 can differ in cosmetic detail (quote style, module qualification, re-export resolution). Without normalization, those cosmetic differences surface as false-positive "Changed" and "Removed" entries even when the source commit has not moved. Apply these transforms to both sets symmetrically:
|
|
33
35
|
|
|
34
36
|
- **Quote style on string defaults.** Normalize string-literal defaults in signatures to a single style — e.g., `kind: str = "Hnsw"` ↔ `kind: str = 'Hnsw'`. Pick one canonical form and apply to both sides.
|
|
35
37
|
- **Module qualification of stdlib helpers.** Strip module prefixes on well-known stdlib helpers when the unqualified form is importable at the call site: `dataclasses.field(...)` → `field(...)`, `typing.Optional[...]` → `Optional[...]`, `typing.List[...]` → `List[...]`. Do not collapse user-defined namespaces.
|
|
36
|
-
- **Public-API re-export resolution.** When `{source_root}/**/__init__.py` re-exports an internal symbol under a different public name (`from .internal import _Impl as Public`, or via `__all__`), resolve both sides to the public name before key-matching — otherwise a renamed re-export in the current scan shows up as "Removed `_Impl`" + "Added `Public`" instead of matching the baseline entry.
|
|
38
|
+
- **Public-API re-export resolution.** When `{source_root}/**/__init__.py` re-exports an internal symbol under a different public name (`from .internal import _Impl as Public`, or via `__all__`), resolve both sides to the public name before key-matching — otherwise a renamed re-export in the current scan shows up as "Removed `_Impl`" + "Added `Public`" instead of matching the baseline entry. The re-export map is already in workflow context as `{reexport_map}` (produced by `skf-load-provenance.py normalize` in step 1 §4). Apply it directly without re-walking `__init__.py` files.
|
|
37
39
|
|
|
38
|
-
Record the set of transforms actually applied in workflow context — step
|
|
40
|
+
Record the set of transforms actually applied in workflow context — step 6 surfaces them in the Provenance section so a reviewer can tell which differences the diff collapsed and which were real.
|
|
39
41
|
|
|
40
42
|
Normalize both sets for comparison:
|
|
41
43
|
- Match by canonicalized export name (primary key)
|
|
42
44
|
- Group by file for location-aware comparison
|
|
43
45
|
|
|
44
|
-
> **Longer-term fix.** The principled remedy is to persist `skf-create-skill`'s ast-grep ruleset to `{forge_version}/extraction-rules.yaml` at create time and have step
|
|
46
|
+
> **Longer-term fix.** The principled remedy is to persist `skf-create-skill`'s ast-grep ruleset to `{forge_version}/extraction-rules.yaml` at create time and have step 2 replay that exact ruleset. When the file is present, step 2 extraction becomes reproducible against the baseline and the canonicalization pass above becomes a no-op. Until then, normalization is the salvage remediation for provenance maps that predate extractor pinning.
|
|
45
47
|
|
|
46
48
|
### 2. Detect Added Exports
|
|
47
49
|
|
|
@@ -87,16 +89,26 @@ For each changed export, record:
|
|
|
87
89
|
|
|
88
90
|
**Only execute if provenance-map.json contains `file_entries`.**
|
|
89
91
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
92
|
+
Run one deterministic comparison subprocess — it walks tracked file_entries[] AND the inverse direction (source-tree → candidate set in standard script/asset/doc directories) so the LLM does not orchestrate per-file hashing:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
uv run {compareFileHashesScript} compare {provenanceMap} {sourceRoot}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Parse the emitted JSON:
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
{
|
|
102
|
+
"added": ["<rel-path>", ...], // present on disk in tracked dirs, NOT in file_entries
|
|
103
|
+
"removed": ["<rel-path>", ...], // in file_entries, missing on disk
|
|
104
|
+
"changed": [{"path": "...", "stored_hash": "sha256:...", "current_hash": "sha256:..."}],
|
|
105
|
+
"stats": {"added": N, "removed": N, "changed": N, "unchanged": N}
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Hash-prefix normalization (writer-vs-reader compatibility — `skf-create-skill` writes `content_hash` with a `"sha256:"` prefix, a bare-hex hash from `hashlib` would otherwise never match) is handled inside the script. Downstream consumers read `added`/`removed`/`changed` directly with no further normalization.
|
|
98
110
|
|
|
99
|
-
Append
|
|
111
|
+
Append the three lists into the Structural Drift section as "### Script/Asset Drift ({stats.added + stats.removed + stats.changed})".
|
|
100
112
|
|
|
101
113
|
### Stack-Specific Structural Diff
|
|
102
114
|
|
|
@@ -164,7 +176,7 @@ Append to {outputFile}:
|
|
|
164
176
|
### 6. Update Report and Auto-Proceed
|
|
165
177
|
|
|
166
178
|
Update {outputFile} frontmatter:
|
|
167
|
-
- Append `'
|
|
179
|
+
- Append `'structural-diff'` to `stepsCompleted`
|
|
168
180
|
|
|
169
181
|
### 7. Present MENU OPTIONS
|
|
170
182
|
|
|
@@ -13,6 +13,14 @@ A good skill brief sets a tight, cohesive boundary: one capability with 3-8 prim
|
|
|
13
13
|
|
|
14
14
|
Brief-skill is split from create-skill so the scoping conversation runs *once*, on cheap signals (manifests, top-level exports, intent), without paying for AST extraction. Compilation is expensive; scoping decisions are cheap to revise. Keeping them in separate workflows lets a user iterate on the brief, share it for review, and re-run create-skill against the same brief whenever the upstream version moves.
|
|
15
15
|
|
|
16
|
+
## Conventions
|
|
17
|
+
|
|
18
|
+
- Bare paths (e.g. `references/<name>.md`) resolve from the skill root.
|
|
19
|
+
- `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.
|
|
20
|
+
- `{skill-root}` resolves to this skill's installed directory (where `customize.toml` lives, if present).
|
|
21
|
+
- `{project-root}`-prefixed paths resolve from the project working directory.
|
|
22
|
+
- `{skill-name}` resolves to the skill directory's basename.
|
|
23
|
+
|
|
16
24
|
## Role
|
|
17
25
|
|
|
18
26
|
You are a skill scoping architect collaborating with a developer who wants to create an agent skill. You bring expertise in source code analysis, API surface identification, and skill boundary design, while the user brings their domain knowledge and specific use case. Work together as equals.
|
|
@@ -21,11 +29,9 @@ You are a skill scoping architect collaborating with a developer who wants to cr
|
|
|
21
29
|
|
|
22
30
|
These rules apply to every step in this workflow:
|
|
23
31
|
|
|
24
|
-
- Read each step file completely before taking any action
|
|
25
|
-
- Follow the mandatory sequence in each step exactly — do not skip, reorder, or optimize
|
|
26
32
|
- Only load one step file at a time — never preload future steps
|
|
27
33
|
- **Lazy-load references and assets:** `references/*.md` and `assets/*.md` files are loaded inside the section that needs them, not at step entry. If a section is skipped (e.g. `version-resolution.md` when `{extractPublicApiScript}` already returned a version, `scope-templates.md` for the `docs-only` branch that bypasses §2c), do not load that file. Each unnecessary load costs context (~5-10 KB per reference) and biases the LLM toward consulting material the current path does not need.
|
|
28
|
-
- Always communicate in `{communication_language}` (the language for user-facing prose). Written artifact text — the `description`, `notes`, and other free-form fields persisted into `skill-brief.yaml` — is in `{document_output_language}`; per-step rules call this out where it applies (see step
|
|
34
|
+
- Always communicate in `{communication_language}` (the language for user-facing prose). Written artifact text — the `description`, `notes`, and other free-form fields persisted into `skill-brief.yaml` — is in `{document_output_language}`; per-step rules call this out where it applies (see step 5). The two values may be the same.
|
|
29
35
|
- If `{headless_mode}` is true, auto-proceed through confirmation gates with their default action and log each auto-decision
|
|
30
36
|
|
|
31
37
|
## On Activation
|
|
@@ -35,27 +41,51 @@ These rules apply to every step in this workflow:
|
|
|
35
41
|
|
|
36
42
|
2. **Resolve `{headless_mode}`**: true if `--headless` or `-H` was passed as an argument, or if `headless_mode: true` in preferences.yaml. Default: false.
|
|
37
43
|
|
|
38
|
-
3.
|
|
44
|
+
3. **Resolve workflow customization.** Run:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
python3 {project-root}/_bmad/scripts/resolve_customization.py \
|
|
48
|
+
--skill {skill-root} --key workflow
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
The script merges the three customization layers per `bmad-customize`'s structural merge rules (scalars override, arrays append):
|
|
52
|
+
|
|
53
|
+
- `{skill-root}/customize.toml` — bundled defaults
|
|
54
|
+
- `_bmad/custom/<skill-name>.toml` under `{project-root}` — team overrides (committed)
|
|
55
|
+
- `_bmad/custom/<skill-name>.user.toml` under `{project-root}` — personal overrides (gitignored)
|
|
56
|
+
|
|
57
|
+
If the script fails or is missing, fall back to reading `{skill-root}/customize.toml` directly — the bundled defaults are an empty string for each path scalar.
|
|
58
|
+
|
|
59
|
+
Apply the path-scalar fallback now so stage files don't have to repeat the conditional logic. For each of the three scalars, if the merged value is empty or absent, use the bundled default:
|
|
60
|
+
|
|
61
|
+
- `{descriptionVoiceExamplesPath}` ← `workflow.description_voice_examples_path` if non-empty, else `assets/description-voice-examples.md`
|
|
62
|
+
- `{scopeTemplatesPath}` ← `workflow.scope_templates_path` if non-empty, else `assets/scope-templates.md`
|
|
63
|
+
- `{briefSchemaPath}` ← `workflow.brief_schema_path` if non-empty, else `assets/skill-brief-schema.md`
|
|
64
|
+
|
|
65
|
+
Stash all three as workflow-context variables. Stage files reference `{descriptionVoiceExamplesPath}` / `{scopeTemplatesPath}` / `{briefSchemaPath}` directly — no conditional at the usage site. Empty-string overrides cleanly fall through to the bundled default; non-empty values let orgs swap in house-style copies without forking the skill.
|
|
66
|
+
|
|
67
|
+
4. Load, read the full file, and execute `references/gather-intent.md`.
|
|
39
68
|
|
|
40
69
|
## Stages
|
|
41
70
|
|
|
42
71
|
| # | Step | File | Auto-proceed |
|
|
43
72
|
|---|------|------|--------------|
|
|
44
|
-
| 1 | Gather Intent |
|
|
45
|
-
| 2 | Analyze Target |
|
|
46
|
-
| 3 | Scope Definition |
|
|
47
|
-
| 4 | Confirm Brief |
|
|
48
|
-
| 5 | Write Brief |
|
|
49
|
-
| 6 | Workflow Health Check (terminal) |
|
|
73
|
+
| 1 | Gather Intent | references/gather-intent.md | No (interactive) |
|
|
74
|
+
| 2 | Analyze Target | references/analyze-target.md | Yes |
|
|
75
|
+
| 3 | Scope Definition | references/scope-definition.md | No (interactive) |
|
|
76
|
+
| 4 | Confirm Brief | references/confirm-brief.md | No (confirm) |
|
|
77
|
+
| 5 | Write Brief | references/write-brief.md | Yes |
|
|
78
|
+
| 6 | Workflow Health Check (terminal) | references/health-check.md | Yes |
|
|
50
79
|
|
|
51
80
|
## Invocation Contract
|
|
52
81
|
|
|
53
82
|
| Aspect | Detail |
|
|
54
83
|
|--------|--------|
|
|
55
84
|
| **Inputs** | `target_repo` [required], `skill_name` [required], `scope_hint` [optional], `language_hint` [optional], `target_version` [optional], `source_authority` [optional: official/community/internal, default community], `source_type` [optional: source/docs-only, default source], `doc_urls` [optional: list of `url[,label]` for source_type=docs-only or supplemental], `scope_type` [optional: full-library/specific-modules/public-api/component-library/reference-app/docs-only], `include` [optional: comma-separated globs], `exclude` [optional: comma-separated globs], `scripts_intent` [optional: detect/none/free-text, default detect], `assets_intent` [optional: detect/none/free-text, default detect], `intent` [optional: free-text used to derive description], `force` [optional: overwrite existing brief without prompting] |
|
|
56
|
-
| **Gates** | step
|
|
85
|
+
| **Gates** | step 1: Input Gate [use args] | step 3: Confirm Gate [C] | step 4: Confirm Gate [C] |
|
|
57
86
|
| **Outputs** | `skill-brief.yaml` at `{forge_data_folder}/{skill-name}/skill-brief.yaml`; final `SKF_BRIEF_RESULT_JSON` line on stdout when `{headless_mode}` is true |
|
|
58
87
|
| **Headless** | All gates auto-resolve with heuristic-driven or default action when `{headless_mode}` is true; pre-supplied inputs consumed at the gates that would otherwise prompt; absent `source_authority` and `scope_type` are resolved by signal-driven detection (see `references/headless-args.md`); existing briefs are preserved unless `--force` was supplied (HALT with `overwrite-cancelled` otherwise) |
|
|
88
|
+
| **Transient-failure retry** | This workflow does **not** auto-retry network or subprocess failures. A failed `gh` fetch (analyze-target.md §1, portfolio-similarity-check.md), QMD probe, or extraction script is logged and surfaced in the final result envelope as a warning, but the workflow continues with whatever signal it has. Headless pipelines that want retry semantics should wrap the invocation at their orchestrator level (e.g. CI re-runner on non-zero exit). Rationale: brief-skill is read-mostly with one terminal write (the YAML at step 5); a partial-signal retry has more failure modes than just re-running the whole workflow, which is cheap. |
|
|
59
89
|
| **Exit codes** | See "Exit Codes" below |
|
|
60
90
|
|
|
61
91
|
## Exit Codes
|
|
@@ -64,16 +94,16 @@ Every HARD HALT in this workflow exits with a stable code so headless automators
|
|
|
64
94
|
|
|
65
95
|
| Code | Meaning | Raised by |
|
|
66
96
|
| ---- | -------------------- | ------------------------------------------------------------------------------------------ |
|
|
67
|
-
| 0 | success | step
|
|
68
|
-
| 2 | input-missing / input-invalid | step
|
|
69
|
-
| 3 | resolution-failure | step
|
|
70
|
-
| 4 | write-failure | step
|
|
71
|
-
| 5 | overwrite-cancelled | step
|
|
72
|
-
| 6 | user-cancelled | any interactive menu in step
|
|
97
|
+
| 0 | success | step 6 (terminal) |
|
|
98
|
+
| 2 | input-missing / input-invalid | step 1 GATE — required headless arg absent (`target_repo`, `skill_name`, or `doc_urls` when `source_type=docs-only`) → `input-missing`; enum violation, malformed semver, non-kebab `skill_name`, or step 5 brief-context schema validation failure → `input-invalid` |
|
|
99
|
+
| 3 | resolution-failure | step 1 §1 (`forge-tier.yaml` missing); step 2 §1 (target inaccessible / `gh auth` fails) |
|
|
100
|
+
| 4 | write-failure | step 1 §1 pre-flight write probe (data folder unwritable: read-only mount, disk full, permissions denied); step 5 §4 (write to `{forge_data_folder}/{skill-name}/skill-brief.yaml` failed) |
|
|
101
|
+
| 5 | overwrite-cancelled | step 5 §2 (existing brief, `force` not supplied) |
|
|
102
|
+
| 6 | user-cancelled | any interactive menu in step 1/03/04 (user selected `[X]` Cancel and exit) |
|
|
73
103
|
|
|
74
104
|
## Result Contract (Headless)
|
|
75
105
|
|
|
76
|
-
When `{headless_mode}` is true, step
|
|
106
|
+
When `{headless_mode}` is true, step 5 emits a single-line JSON envelope on **stdout** before chaining to step 6, and every HARD HALT emits the same envelope shape on **stderr** with `status: "error"`:
|
|
77
107
|
|
|
78
108
|
```
|
|
79
109
|
SKF_BRIEF_RESULT_JSON: {"status":"success|error","brief_path":"…|null","skill_name":"…","version":"…|null","language":"…|null","scope_type":"…|null","exit_code":0,"halt_reason":null}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Description Voice Examples
|
|
2
2
|
|
|
3
|
-
Loaded by step
|
|
3
|
+
Loaded by step 1 §7b only. The five examples below show the *range* of acceptable voices for the `description` field — they vary in lead, structure, and trigger phrasing on purpose. The point is to anchor the LLM to "two facts must come through (what the skill is, when to use it); everything else is voice — do not template-stamp."
|
|
4
4
|
|
|
5
5
|
## Examples
|
|
6
6
|
|
|
@@ -46,7 +46,7 @@ If the source is a remote GitHub repo, use `gh api repos/{owner}/{repo}/contents
|
|
|
46
46
|
|
|
47
47
|
If detection succeeds, use the detected version. If it fails or returns a non-semver value, fall back to `"1.0.0"`.
|
|
48
48
|
|
|
49
|
-
The create-skill workflow (
|
|
49
|
+
The create-skill workflow (extract) also performs version reconciliation at extraction time — if the source version has changed since the brief was created, the extraction step warns and uses the source version.
|
|
50
50
|
|
|
51
51
|
**Target version override:** When `target_version` is present in the brief, it takes precedence over auto-detection. Auto-detection still runs for informational purposes (displayed as "Detected version" alongside the user-specified "Target version"), but the `target_version` value is used as the brief's `version` field. This is particularly useful for docs-only skills (where no package manifest exists) and when the user wants to compile a skill for a specific older version.
|
|
52
52
|
|
|
@@ -67,6 +67,14 @@ scope:
|
|
|
67
67
|
# - "code/core/src/manager-api/**"
|
|
68
68
|
# - "code/core/src/preview-api/**"
|
|
69
69
|
notes: "Optional notes about scope decisions"
|
|
70
|
+
# Optional: authoring-time scope-type rationale (written once by brief-skill 2c)
|
|
71
|
+
# rationale:
|
|
72
|
+
# recommended: full-library
|
|
73
|
+
# chosen: public-api
|
|
74
|
+
# accepted_recommendation: false
|
|
75
|
+
# heuristic: narrow-public-api
|
|
76
|
+
# reason: "user overrode full-library->public-api: only documented API ships"
|
|
77
|
+
# recorded: "2026-05-18"
|
|
70
78
|
# Optional: amendment log for scope decisions made during create-skill §2a,
|
|
71
79
|
# update-skill §1b (auth-doc), and update-skill §1c (scope-expansion).
|
|
72
80
|
# amendments:
|
|
@@ -94,6 +102,28 @@ scope:
|
|
|
94
102
|
# - "**/*.stories.*"
|
|
95
103
|
```
|
|
96
104
|
|
|
105
|
+
### Scope Rationale (Optional)
|
|
106
|
+
|
|
107
|
+
`scope.rationale` is a single optional object recording **why the scope type was chosen at authoring time**. Unlike `scope.amendments[]` (an additive log that accumulates post-authoring decisions across workflow runs), `scope.rationale` is one decision, written once by `skf-brief-skill` step 03 §2c and revised in place on a step-4 `[R]` re-entry. It sits structurally beside `scope.amendments`, reusing the same structured / script-readable / human-auditable ethos rather than a prose decision log.
|
|
108
|
+
|
|
109
|
+
**Fields:**
|
|
110
|
+
|
|
111
|
+
| Field | Type | Required | Source |
|
|
112
|
+
|---|---|---|---|
|
|
113
|
+
| `recommended` | string (one of the six `scope.type` values) | yes | `skf-recommend-scope-type.py` → `scope_type` |
|
|
114
|
+
| `chosen` | string (one of the six) | yes | final `scope.type` |
|
|
115
|
+
| `accepted_recommendation` | bool | yes | `chosen == recommended` |
|
|
116
|
+
| `heuristic` | string | yes | script `matched_heuristic` |
|
|
117
|
+
| `reason` | string | yes | accepted → script `rationale` verbatim; overridden → user's stated reason, or `"user overrode {recommended}->{chosen}; reason not stated"` |
|
|
118
|
+
| `recorded` | string (ISO date `YYYY-MM-DD`) | yes | current date — mirrors `amendments[].date` |
|
|
119
|
+
|
|
120
|
+
**Who reads `scope.rationale`:**
|
|
121
|
+
|
|
122
|
+
- Humans reviewing the brief — it records why the boundary was drawn the way it was.
|
|
123
|
+
- `skf-update-skill` Update intent MAY later surface conflicts against it (e.g., a scope change that contradicts the original authoring decision). **Not implemented now — deferred.** The field is forward-compatible; the reader is wired later.
|
|
124
|
+
|
|
125
|
+
**Backward compatibility:** `scope.rationale` is optional. Briefs without this field validate unchanged — treat missing as absent (null). Mirrors the `scope.amendments` backward-compat rule.
|
|
126
|
+
|
|
97
127
|
### Scope Amendments (Optional)
|
|
98
128
|
|
|
99
129
|
`scope.amendments[]` is an additive, optional audit log of scope decisions made by workflows after the brief was first authored. Two writer paths exist today:
|
|
@@ -171,7 +201,7 @@ scope:
|
|
|
171
201
|
|
|
172
202
|
## Human-Readable Presentation Format
|
|
173
203
|
|
|
174
|
-
The runtime template lives in `
|
|
204
|
+
The runtime template lives in `references/confirm-brief.md` §2 — that is the single source of truth for how the brief is rendered for user confirmation (brief-skill step 4 only; analyze-source batch generation does not render). If the rendering format needs to change, edit the step file. This asset documents the data contract; the step owns the presentation.
|
|
175
205
|
|
|
176
206
|
## Validation Rules
|
|
177
207
|
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# DO NOT EDIT -- overwritten on every update.
|
|
2
|
+
#
|
|
3
|
+
# Workflow customization surface for skf-brief-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 brief authoring 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
|
+
# (house style, naming conventions, description-voice guardrails).
|
|
25
|
+
# Overrides append.
|
|
26
|
+
#
|
|
27
|
+
# Each entry is either:
|
|
28
|
+
# - a literal sentence, e.g. "Skill briefs must cite an authoritative source."
|
|
29
|
+
# - a file reference prefixed with `file:`, e.g.
|
|
30
|
+
# "file:{project-root}/docs/brief-style.md" (globs supported; file
|
|
31
|
+
# contents are loaded and treated as facts).
|
|
32
|
+
|
|
33
|
+
persistent_facts = [
|
|
34
|
+
"file:{project-root}/**/project-context.md",
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
# --- Optional asset overrides ---
|
|
38
|
+
#
|
|
39
|
+
# Lift the canonical asset paths so orgs can substitute house-style copies
|
|
40
|
+
# without forking the skill. Empty string = use the bundled default.
|
|
41
|
+
|
|
42
|
+
description_voice_examples_path = ""
|
|
43
|
+
scope_templates_path = ""
|
|
44
|
+
brief_schema_path = ""
|
package/src/skf-brief-skill/{steps-c/step-02-analyze-target.md → references/analyze-target.md}
RENAMED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
---
|
|
2
|
-
nextStepFile: '
|
|
2
|
+
nextStepFile: 'scope-definition.md'
|
|
3
3
|
versionResolutionFile: 'references/version-resolution.md'
|
|
4
4
|
extractPublicApiScript: '{project-root}/src/shared/scripts/skf-extract-public-api.py'
|
|
5
5
|
detectWorkspacesScript: '{project-root}/src/shared/scripts/skf-detect-workspaces.py'
|
|
6
6
|
detectLanguageScript: '{project-root}/src/shared/scripts/skf-detect-language.py'
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
+
<!-- Config: communicate in {communication_language}. -->
|
|
10
|
+
|
|
9
11
|
# Step 2: Analyze Target
|
|
10
12
|
|
|
11
13
|
## STEP GOAL:
|
|
@@ -21,8 +23,6 @@ To analyze the target repository by resolving its location, reading its structur
|
|
|
21
23
|
|
|
22
24
|
## MANDATORY SEQUENCE
|
|
23
25
|
|
|
24
|
-
**CRITICAL:** Follow this sequence exactly. Do not skip, reorder, or improvise unless user explicitly requests a change.
|
|
25
|
-
|
|
26
26
|
### 1. Resolve Target Location
|
|
27
27
|
|
|
28
28
|
**For GitHub URLs:**
|
|
@@ -79,7 +79,7 @@ This looks like a monorepo ({manifest_kind}) with these workspaces:
|
|
|
79
79
|
1. {workspaces[0].name} ({workspaces[0].path})
|
|
80
80
|
2. {workspaces[1].name} ({workspaces[1].path})
|
|
81
81
|
...
|
|
82
|
-
Which one should the skill cover? Pick a number, type 'all' to scope at the repo root
|
|
82
|
+
Which one should the skill cover? Pick a number, or type 'all' to scope at the repo root.
|
|
83
83
|
```
|
|
84
84
|
|
|
85
85
|
Interactive: wait for the user choice. On a numbered choice, store `monorepo_workspace: {path}` and rebase §2-§4b against that path. On `'all'`, leave `monorepo_workspace` unset and proceed at the repo root with a note in the analysis summary that scope is unfiltered.
|
|
@@ -268,5 +268,5 @@ Pause briefly for user input. If the user provides corrections or asks questions
|
|
|
268
268
|
|
|
269
269
|
## CRITICAL STEP COMPLETION NOTE
|
|
270
270
|
|
|
271
|
-
ONLY WHEN the analysis is complete and the summary has been presented to the user will you load and read fully
|
|
271
|
+
ONLY WHEN the analysis is complete and the summary has been presented to the user will you load and read fully `scope-definition.md` to begin scope definition.
|
|
272
272
|
|
package/src/skf-brief-skill/{steps-c/step-04-confirm-brief.md → references/confirm-brief.md}
RENAMED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
---
|
|
2
|
-
nextStepFile: '
|
|
3
|
-
reviseStepFile: '
|
|
2
|
+
nextStepFile: 'write-brief.md'
|
|
3
|
+
reviseStepFile: 'scope-definition.md'
|
|
4
4
|
briefSchemaFile: 'assets/skill-brief-schema.md'
|
|
5
5
|
advancedElicitationSkill: '/bmad-advanced-elicitation'
|
|
6
6
|
partyModeSkill: '/bmad-party-mode'
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
+
<!-- Config: communicate in {communication_language}. -->
|
|
10
|
+
|
|
9
11
|
# Step 4: Confirm Brief
|
|
10
12
|
|
|
11
13
|
## STEP GOAL:
|
|
@@ -20,11 +22,9 @@ To present the complete skill brief in human-readable format, highlighting all f
|
|
|
20
22
|
|
|
21
23
|
## MANDATORY SEQUENCE
|
|
22
24
|
|
|
23
|
-
**CRITICAL:** Follow this sequence exactly. Do not skip, reorder, or improvise unless user explicitly requests a change.
|
|
24
|
-
|
|
25
25
|
### 1. Assemble Complete Brief
|
|
26
26
|
|
|
27
|
-
Use the values already accepted in steps 01-03 directly — do not re-load `{
|
|
27
|
+
Use the values already accepted in steps 01-03 directly — do not re-load `{briefSchemaPath}` here. The 18 fields below are all in conversation; the schema is only consulted in §4 if an inline adjustment needs a specific field's validation rule cited.
|
|
28
28
|
|
|
29
29
|
Compile all gathered data from steps 01-03 into the complete brief:
|
|
30
30
|
|
|
@@ -41,6 +41,7 @@ Compile all gathered data from steps 01-03 into the complete brief:
|
|
|
41
41
|
- **scope.include:** {include patterns from step 03}
|
|
42
42
|
- **scope.exclude:** {exclude patterns from step 03}
|
|
43
43
|
- **scope.notes:** {any scope notes from step 03}
|
|
44
|
+
- **scope.rationale:** {recommended -> chosen, reason — from step 03}
|
|
44
45
|
- **source_type:** {source or docs-only, from step 01}
|
|
45
46
|
- **doc_urls:** {collected documentation URLs with labels, from steps 01/03 — include if source_type is "docs-only" or supplemental URLs were collected}
|
|
46
47
|
- **scripts_intent:** {detect/none/description from step 03, or "detect" if not explicitly set}
|
|
@@ -68,6 +69,8 @@ Scope: {scope.type}
|
|
|
68
69
|
Include: {scope.include patterns, one per line}
|
|
69
70
|
Exclude: {scope.exclude patterns, one per line}
|
|
70
71
|
Notes: {scope.notes}
|
|
72
|
+
Rationale: {chosen} chosen over {recommended} — {reason}
|
|
73
|
+
{omit this line entirely if scope.rationale absent}
|
|
71
74
|
|
|
72
75
|
{If source_type is "docs-only":}
|
|
73
76
|
Source Type: docs-only
|
|
@@ -108,7 +111,7 @@ Glosses (substitute the matching one-liner for `{tier_gloss}`, `{scripts_gloss}`
|
|
|
108
111
|
- `none`: no script/asset packaging — create-skill will skip the detection pass
|
|
109
112
|
- free-text (anything else): a description of what to package; create-skill treats it as the user's spec
|
|
110
113
|
|
|
111
|
-
(For `docs-only` and `public-api` scope types the scripts/assets prompt is skipped in step
|
|
114
|
+
(For `docs-only` and `public-api` scope types the scripts/assets prompt is skipped in step 3 §5b — the values default to `detect` but the create-skill detection pass also no-ops for these scope types, so the gloss just clarifies that the recorded value will not actually fire any scan.)"
|
|
112
115
|
|
|
113
116
|
### 3. Highlight Items Needing Attention
|
|
114
117
|
|
|
@@ -117,7 +120,7 @@ Flag any fields that may need review:
|
|
|
117
120
|
{If language was overridden or low confidence:}
|
|
118
121
|
"**Note:** Language was {auto-detected / manually overridden}."
|
|
119
122
|
|
|
120
|
-
"**Description:** synthesized and confirmed in step
|
|
123
|
+
"**Description:** synthesized and confirmed in step 1 §7b. This is the text agents read when deciding whether to route to your skill — refine here if you want to tighten it now that the full brief is visible."
|
|
121
124
|
|
|
122
125
|
{If forge tier was defaulted:}
|
|
123
126
|
"**Note:** Forge tier defaulted to Quick (no forge-tier.yaml found)."
|
|
@@ -138,7 +141,7 @@ You can:
|
|
|
138
141
|
### 4. Handle Inline Adjustments
|
|
139
142
|
|
|
140
143
|
If the user requests changes to specific fields (name, description, version, etc.):
|
|
141
|
-
- If the adjustment requires explaining a field's validation rule or allowed values, load `{
|
|
144
|
+
- If the adjustment requires explaining a field's validation rule or allowed values, load `{briefSchemaPath}` now (otherwise skip the read — the common path does not need it)
|
|
142
145
|
- Make the adjustment
|
|
143
146
|
- Re-present the updated brief
|
|
144
147
|
- Return to the menu
|
|
@@ -153,7 +156,7 @@ Display: **Select an Option:** [R] Revise Scope [A] Advanced Elicitation [P] Par
|
|
|
153
156
|
- IF A: Invoke {advancedElicitationSkill}, and when finished redisplay the menu
|
|
154
157
|
- IF P: Invoke {partyModeSkill}, and when finished redisplay the menu
|
|
155
158
|
- IF C: Load, read entire file, then execute {nextStepFile}
|
|
156
|
-
- IF X: Treat as user-cancellation. Display `"Cancelled — no brief was written."` and HALT (exit code 6, `halt_reason: "user-cancelled"`). Cancellation here is non-destructive — step
|
|
159
|
+
- IF X: Treat as user-cancellation. Display `"Cancelled — no brief was written."` and HALT (exit code 6, `halt_reason: "user-cancelled"`). Cancellation here is non-destructive — step 5 has not run, no skill-brief.yaml file exists yet. `[X]` is interactive-only; the headless GATE never reaches this branch.
|
|
157
160
|
- IF Any other comments or queries: help user respond, apply any field adjustments, re-present brief if changed, then [Redisplay Menu Options](#5-present-menu-options)
|
|
158
161
|
|
|
159
162
|
#### EXECUTION RULES:
|
|
@@ -166,5 +169,5 @@ Display: **Select an Option:** [R] Revise Scope [A] Advanced Elicitation [P] Par
|
|
|
166
169
|
|
|
167
170
|
## CRITICAL STEP COMPLETION NOTE
|
|
168
171
|
|
|
169
|
-
ONLY WHEN C is selected and the user has explicitly approved the brief will you load and read fully
|
|
172
|
+
ONLY WHEN C is selected and the user has explicitly approved the brief will you load and read fully `write-brief.md` to write the skill-brief.yaml file.
|
|
170
173
|
|