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,7 +1,9 @@
|
|
|
1
1
|
---
|
|
2
|
-
nextStepFile: '
|
|
2
|
+
nextStepFile: 'write.md'
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
+
<!-- Config: communicate in {communication_language}. -->
|
|
6
|
+
|
|
5
7
|
# Step 5: Validate
|
|
6
8
|
|
|
7
9
|
## STEP GOAL:
|
|
@@ -16,8 +18,6 @@ Validate the merged skill content against the agentskills.io specification, veri
|
|
|
16
18
|
|
|
17
19
|
## MANDATORY SEQUENCE
|
|
18
20
|
|
|
19
|
-
**CRITICAL:** Follow this sequence exactly. Do not skip, reorder, or improvise unless user explicitly requests a change.
|
|
20
|
-
|
|
21
21
|
### 1. Check Tool Availability and Validation Timing
|
|
22
22
|
|
|
23
23
|
Run: `npx skill-check -h`
|
|
@@ -27,7 +27,7 @@ Run: `npx skill-check -h`
|
|
|
27
27
|
|
|
28
28
|
**Important:** Do not assume availability — empirical check required.
|
|
29
29
|
|
|
30
|
-
**Validation timing note:** Step-04 section 6b has already written SKILL.md (and stack reference files) to disk. External-tool checks against written files (skill-check Checks A, E, F) still run in **step
|
|
30
|
+
**Validation timing note:** Step-04 section 6b has already written SKILL.md (and stack reference files) to disk. External-tool checks against written files (skill-check Checks A, E, F) still run in **step 6 section 7** to co-locate external-tool validation with post-write verification. Structural checks (B, C, D) run here against the merged content — content on disk is byte-identical to the in-context copy.
|
|
31
31
|
|
|
32
32
|
### 2. Launch Parallel Validation Checks
|
|
33
33
|
|
|
@@ -35,7 +35,7 @@ Launch subprocesses in parallel for each validation category, aggregating result
|
|
|
35
35
|
|
|
36
36
|
**Check A — Spec Compliance (deferred to post-write):**
|
|
37
37
|
|
|
38
|
-
Skill-check requires written files on disk. This check is deferred to step
|
|
38
|
+
Skill-check requires written files on disk. This check is deferred to step 6 section 7. Perform manual structural check only: verify merged SKILL.md has required sections (exports, usage patterns, conventions), verify export entries have name/type/signature/file:line reference, flag missing sections.
|
|
39
39
|
|
|
40
40
|
**Check B — [MANUAL] Section Integrity:**
|
|
41
41
|
- Compare [MANUAL] inventory from step 01 against merged content
|
|
@@ -1,64 +1,65 @@
|
|
|
1
1
|
---
|
|
2
|
-
nextStepFile: '
|
|
2
|
+
nextStepFile: 'report.md'
|
|
3
|
+
descriptionGuardProtocol: '{project-root}/src/shared/references/description-guard-protocol.md'
|
|
4
|
+
# Resolve `{descriptionGuardHelper}` by probing `{descriptionGuardProbeOrder}`
|
|
5
|
+
# in order (installed SKF module path first, src/ dev-checkout fallback);
|
|
6
|
+
# first existing path wins. HALT if neither resolves — letting an external
|
|
7
|
+
# tool's rewrite of the merged description field stand would silently
|
|
8
|
+
# regress discovery quality and re-introduce angle-bracket tokens.
|
|
9
|
+
descriptionGuardProbeOrder:
|
|
10
|
+
- '{project-root}/_bmad/skf/shared/scripts/skf-description-guard.py'
|
|
11
|
+
- '{project-root}/src/shared/scripts/skf-description-guard.py'
|
|
12
|
+
# Resolve `{updateActiveSymlinkHelper}` to the first existing path; HALT if
|
|
13
|
+
# neither candidate exists. §5b uses it to atomically flip the active
|
|
14
|
+
# symlink; §6 uses it (verify mode) to confirm the post-state. Without
|
|
15
|
+
# the helper, §5b's "rm and recreate" pattern leaves a brief window where
|
|
16
|
+
# concurrent readers see a missing symlink.
|
|
17
|
+
updateActiveSymlinkProbeOrder:
|
|
18
|
+
- '{project-root}/_bmad/skf/shared/scripts/skf-update-active-symlink.py'
|
|
19
|
+
- '{project-root}/src/shared/scripts/skf-update-active-symlink.py'
|
|
3
20
|
---
|
|
4
21
|
|
|
22
|
+
<!-- Config: communicate in {communication_language}. -->
|
|
23
|
+
|
|
5
24
|
# Step 6: Write Updated Files
|
|
6
25
|
|
|
7
26
|
## STEP GOAL:
|
|
8
27
|
|
|
9
|
-
Verify the merged SKILL.md and stack reference files that step
|
|
28
|
+
Verify the merged SKILL.md and stack reference files that step 4 section 6b wrote to disk, then write the derived artifacts (metadata.json, provenance-map.json, evidence-report.md, context-snippet.md, and the active symlink).
|
|
10
29
|
|
|
11
30
|
## Rules
|
|
12
31
|
|
|
13
|
-
- Focus only on verifying merged files and writing derived artifacts — merge content was already written in step
|
|
32
|
+
- Focus only on verifying merged files and writing derived artifacts — merge content was already written in step 4
|
|
14
33
|
- Do not modify merged SKILL.md content — any mismatch detected during verification triggers HALT, not repair
|
|
15
34
|
- Do not skip provenance map update — critical for future audits
|
|
16
35
|
- HALT immediately on verification failure before writing any derived artifact — a partial-write skill package is worse than an unchanged one
|
|
17
36
|
|
|
18
37
|
## MANDATORY SEQUENCE
|
|
19
38
|
|
|
20
|
-
**CRITICAL:** Follow this sequence exactly. Do not skip, reorder, or improvise unless user explicitly requests a change.
|
|
21
|
-
|
|
22
39
|
### 0. Description Guard Protocol
|
|
23
40
|
|
|
24
41
|
**Used by:** §7 (`skill-check check --fix` and `skill-check split-body --write`), and any future tool invocation that may modify SKILL.md's frontmatter on disk.
|
|
25
42
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
To prevent this, any tool invocation in §7 that may touch SKILL.md must run inside the following four-phase guard:
|
|
29
|
-
|
|
30
|
-
1. **Capture.** Before invoking the tool, read `{skill_package}/SKILL.md` frontmatter and snapshot the exact `description` value into a local variable (e.g., `guarded_description`). Capture the in-context copy as well.
|
|
31
|
-
2. **Execute.** Run the tool as specified in its section.
|
|
32
|
-
3. **Verify.** After the tool completes, re-read the on-disk SKILL.md and compare its frontmatter `description` against `guarded_description`. Normalize whitespace for comparison (trim leading/trailing whitespace, collapse internal runs) but do not ignore content differences.
|
|
33
|
-
4. **Restore on divergence.** If the post-tool description differs from `guarded_description` in any way other than whitespace normalization, write `guarded_description` back to the on-disk SKILL.md frontmatter and update the in-context copy to match. Record `description_guard_restored: true` with the tool name in context for the evidence report.
|
|
43
|
+
Load `{descriptionGuardProtocol}` for the full prose explanation of the four-phase guard (why it exists, what counts as divergence, why token-stream comparison is the right shape). The deterministic phases are executed via `{descriptionGuardHelper}` — §7 invokes the helper at the capture and verify-restore points around every `skill-check` call.
|
|
34
44
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
- The description was replaced (different content).
|
|
38
|
-
- The description was truncated (suffix missing).
|
|
39
|
-
- Angle-bracket tokens were re-introduced (should never happen if the prior skill was correctly sanitized, but protect anyway).
|
|
40
|
-
- The field was deleted entirely (extreme tool behavior).
|
|
41
|
-
|
|
42
|
-
**What does NOT count as divergence:** whitespace-only differences (trailing newline, trimmed spaces) — treat as equivalent.
|
|
43
|
-
|
|
44
|
-
**Why this lives in update-skill too:** the guard protocol was first introduced in `skf-create-skill/step-06-validate.md §0` to defend the freshly-compiled description. Update-skill runs the identical `skill-check check --fix` command against the merged skill package in §7, so it faces the same risk and needs the same defense. Keep the two §0 protocols functionally identical — if external tool behavior changes, update both workflows.
|
|
45
|
+
Update-skill does not run the optional post-restore frontmatter re-validation today — the post-write checks in §1 catch downstream issues, and a `restored: true` outcome is already surfaced through the evidence report (§4).
|
|
45
46
|
|
|
46
47
|
### 1. Verify SKILL.md Write
|
|
47
48
|
|
|
48
|
-
SKILL.md was written in step
|
|
49
|
+
SKILL.md was written in step 4 section 6b. Verify the write landed intact before proceeding to any derived-artifact writes.
|
|
49
50
|
|
|
50
51
|
- Read `{skill_package}/SKILL.md` from disk
|
|
51
|
-
- Count `<!-- [MANUAL:*] -->` opening markers and compare against the [MANUAL] inventory captured in step
|
|
52
|
-
- Verify the resolved `{skill_package}` path matches the version directory step
|
|
52
|
+
- Count `<!-- [MANUAL:*] -->` opening markers and compare against the [MANUAL] inventory captured in step 1
|
|
53
|
+
- Verify the resolved `{skill_package}` path matches the version directory step 4 wrote to (if the version changed, step 4 updated `{skill_package}` in context to point at the new path)
|
|
53
54
|
- If [MANUAL] count matches and path resolves: proceed to section 2
|
|
54
55
|
- **If [MANUAL] count does not match: HALT immediately.** Do not write `metadata.json`, `provenance-map.json`, or any other artifact — further writes would compound the inconsistency. Alert the user:
|
|
55
56
|
|
|
56
|
-
"**[MANUAL] section count mismatch after write.** Expected {N} from step
|
|
57
|
+
"**[MANUAL] section count mismatch after write.** Expected {N} from step 1 inventory, found {M} on disk at `{skill_package}/SKILL.md`. The skill package is in an inconsistent state. Manual recovery required — restore the previous version from `{skill_group}/{previous_version}/` or fix the file in place, then re-run update-skill."
|
|
57
58
|
|
|
58
59
|
### 2. Write Updated metadata.json
|
|
59
60
|
|
|
60
61
|
Update `{skill_package}/metadata.json`:
|
|
61
|
-
- Update `version`: **if `update_mode == "gap-driven"`, do not bump — the skill is being repaired against the same source commit, so leave `version` unchanged and update only `generation_date` / `last_update` below.** This keeps metadata `version` consistent with the on-disk `{skill_package}` path, which step
|
|
62
|
+
- Update `version`: **if `update_mode == "gap-driven"`, do not bump — the skill is being repaired against the same source commit, so leave `version` unchanged and update only `generation_date` / `last_update` below.** This keeps metadata `version` consistent with the on-disk `{skill_package}` path, which step 4 §6b also leaves unchanged in gap-driven mode (see step 4 §6b's "If the source version detected during step 3 differs..." carve-out — in gap-driven mode no source version is detected, so step 4 writes into the existing version directory). Otherwise, if a source version was detected during re-extraction and differs from the current metadata version, use the source version; otherwise increment patch version
|
|
62
63
|
- Update `generation_date` timestamp to current ISO-8601 date
|
|
63
64
|
- Update `exports` array to reflect current export list
|
|
64
65
|
- Update `stats` from re-extraction results:
|
|
@@ -77,13 +78,13 @@ Update `{skill_package}/metadata.json`:
|
|
|
77
78
|
|
|
78
79
|
Write to `{forge_version}/provenance-map.json`:
|
|
79
80
|
|
|
80
|
-
**If `no_reextraction == true` (gap-driven mode from step
|
|
81
|
-
Dispatch per-entry on the verification outcome recorded by step
|
|
81
|
+
**If `no_reextraction == true` (gap-driven mode from step 3 section 0):**
|
|
82
|
+
Dispatch per-entry on the verification outcome recorded by step 3 — gap-driven runs produce a mix of `verified`, `moved`, `re-extracted`, and `unknown` outcomes, and each requires a different provenance-map write strategy:
|
|
82
83
|
|
|
83
84
|
- **`verified` exports**: no fresh extraction data exists — do NOT overwrite `confidence`, `extraction_method`, `ast_node_type`, `params[]`, `return_type`, `source_file`, or `source_line`. The provenance entry stays byte-identical.
|
|
84
85
|
- **`moved` exports**: update `source_line` (and `source_file` if different) to the new location recorded by the spot-check. Do not touch other fields.
|
|
85
|
-
- **`re-extracted` exports** (resolved via step
|
|
86
|
-
- **`unknown` exports** (not in provenance map; no `source_citation`; `severity` is `Medium`, `Low`, or `Info`, OR `remediation_paths[]` was empty and §0a did not halt): add new entries with fields populated from step
|
|
86
|
+
- **`re-extracted` exports** (resolved via step 3 §0a's Targeted Re-Extraction Branch from `remediation_paths[]`): write a full entry — `source_file`, `source_line`, `confidence`, `extraction_method`, `ast_node_type`, `params[]`, `return_type` — from §0a's fresh AST extraction record. This is the only gap-driven outcome that produces normal-mode-quality provenance; do NOT fall through to the byte-identical preservation above.
|
|
87
|
+
- **`unknown` exports** (not in provenance map; no `source_citation`; `severity` is `Medium`, `Low`, or `Info`, OR `remediation_paths[]` was empty and §0a did not halt): add new entries with fields populated from step 4 merge output. `source_file`/`source_line` may be `null` here — leave these fields unset rather than writing stale values. **This path is only acceptable for `severity` in `Medium`, `Low`, or `Info`.** A Critical/High `unknown` reaching this branch indicates step 3 §0a was skipped or bypassed and is a workflow bug — step 3 §0a should have halted with status `halted-for-remediation-path` before step 6 ran. If you encounter one, halt with a pointer to §0a rather than writing null citations for a blocking gap.
|
|
87
88
|
- Skip the "For each export in the updated skill" bullets below — they apply only to normal re-extraction mode.
|
|
88
89
|
|
|
89
90
|
**For each export in the updated skill (normal mode only):**
|
|
@@ -160,7 +161,7 @@ Append update operation section to `{forge_version}/evidence-report.md` (create
|
|
|
160
161
|
- Notes: {one-sentence detail or —}
|
|
161
162
|
```
|
|
162
163
|
|
|
163
|
-
**Description Guard population** (used by §7 Post-Write Validation when the §0 protocol fires): fill all four fields from context when `description_guard_restored == true` (triggering tool, whether restore succeeded, what changed). When `Restored: false`, the other three fields are `—` — this is the clean-run expected state. Same field semantics and populator logic as create-skill step
|
|
164
|
+
**Description Guard population** (used by §7 Post-Write Validation when the §0 protocol fires): fill all four fields from context when `description_guard_restored == true` (triggering tool, whether restore succeeded, what changed). When `Restored: false`, the other three fields are `—` — this is the clean-run expected state. Same field semantics and populator logic as create-skill step 6 §8.
|
|
164
165
|
|
|
165
166
|
**Context Snippet population** (used by §5 after the staleness check runs): §4 writes the sub-block with placeholders; §5 updates the on-disk evidence report in place after deciding whether to regenerate. Set `Regenerated: true` and populate `Triggers fired` with any combination of `headline-exports`, `version`, `gotchas` when at least one trigger fired. Set `Regenerated: false` and `Triggers fired: —` when none fired (the gap-driven / internals-only outcome). Always fill `Notes` with a one-sentence reason (e.g., `"Gap-driven repair — no snippet surface changed"`, `"Version bumped 0.1.0 → 0.2.0; headline exports re-ranked"`).
|
|
166
167
|
|
|
@@ -168,11 +169,11 @@ Append update operation section to `{forge_version}/evidence-report.md` (create
|
|
|
168
169
|
|
|
169
170
|
**ONLY if skill_type == "stack":**
|
|
170
171
|
|
|
171
|
-
Stack reference files were written in step
|
|
172
|
+
Stack reference files were written in step 4 section 6b. Verify each affected reference file that the merge produced:
|
|
172
173
|
|
|
173
174
|
- Read each `references/{library}.md` back from disk
|
|
174
175
|
- Read each `references/integrations/{pair}.md` back from disk
|
|
175
|
-
- Verify per-file [MANUAL] section counts match the per-file inventory captured in step
|
|
176
|
+
- Verify per-file [MANUAL] section counts match the per-file inventory captured in step 1
|
|
176
177
|
- **If any verification fails: HALT** using the same recovery protocol as section 1 — do not regenerate `context-snippet.md` or write any further derived artifact
|
|
177
178
|
|
|
178
179
|
**For all skills (both single and stack) — regenerate `context-snippet.md` if stale:**
|
|
@@ -194,36 +195,43 @@ Stack reference files were written in step-04 section 6b. Verify each affected r
|
|
|
194
195
|
- For single skills: `skf-create-skill/assets/skill-sections.md` (pipe-delimited indexed format)
|
|
195
196
|
- For stack skills: `skf-create-stack-skill/assets/stack-skill-template.md`
|
|
196
197
|
|
|
197
|
-
Use the **flat draft form** for the `root:` path in the draft snippet: `root: skills/{skill-name}/`. The per-IDE skill root (e.g., `.claude/skills/`, `.windsurf/skills/`, `.github/skills/` — see `skf-export-skill/assets/managed-section-format.md`) is applied later by `export-skill` step
|
|
198
|
+
Use the **flat draft form** for the `root:` path in the draft snippet: `root: skills/{skill-name}/`. The per-IDE skill root (e.g., `.claude/skills/`, `.windsurf/skills/`, `.github/skills/` — see `skf-export-skill/assets/managed-section-format.md`) is applied later by `export-skill` step 3 when the skill is exported. Do not choose an IDE-specific prefix in update-skill — that is an export-time decision that depends on config.yaml.
|
|
198
199
|
|
|
199
|
-
Pull values for the regenerated snippet from the updated metadata.json (version, top exports), the merged SKILL.md (section anchors, inline summaries), and the evidence report (new gotchas). If gotchas cannot be derived from the updated evidence but the prior snippet has a `|gotchas:` line, carry forward the prior line with the `[CARRIED]` marker — see `skf-export-skill/
|
|
200
|
+
Pull values for the regenerated snippet from the updated metadata.json (version, top exports), the merged SKILL.md (section anchors, inline summaries), and the evidence report (new gotchas). If gotchas cannot be derived from the updated evidence but the prior snippet has a `|gotchas:` line, carry forward the prior line with the `[CARRIED]` marker — see `skf-export-skill/references/generate-snippet.md` for the carry-forward protocol (one-cycle limit).
|
|
200
201
|
|
|
201
202
|
Write the regenerated snippet to `{skill_package}/context-snippet.md`, preserving file permissions.
|
|
202
203
|
|
|
203
204
|
**If skill_type == "stack"**, also verify that the reference file updates from the first half of this section have been applied before writing the snippet so the stack snippet reflects the newest integration list.
|
|
204
205
|
|
|
205
|
-
### 5b. Update Active Symlink
|
|
206
|
+
### 5b. Update Active Symlink
|
|
206
207
|
|
|
207
|
-
|
|
208
|
-
- Create or update the `active` symlink at `{skill_group}/active` pointing to the new `{version}`
|
|
209
|
-
- If the symlink already exists, remove it first and recreate
|
|
208
|
+
Flip `{skill_group}/active` to point at the current `{version}` via the helper. The call is **always** run — atomic, idempotent, and verified in one shot. The helper's no-op path handles the "version did not change" case (gap-driven mode, or no source drift) without writing to disk:
|
|
210
209
|
|
|
211
|
-
```
|
|
212
|
-
{
|
|
210
|
+
```bash
|
|
211
|
+
uv run {updateActiveSymlinkHelper} update \
|
|
212
|
+
--skill-group {skill_group} \
|
|
213
|
+
--version {version}
|
|
213
214
|
```
|
|
214
215
|
|
|
215
|
-
|
|
216
|
+
The helper emits a result envelope with `status` ∈ `{ok, flipped, mismatch, missing-target}` and a pre-formatted `log_message`. Log the message to the evidence report.
|
|
217
|
+
|
|
218
|
+
**Dispatch on `status`:**
|
|
219
|
+
|
|
220
|
+
- **`ok`** (exit 0): symlink already points at `{version}` — no disk write. Continue to §6.
|
|
221
|
+
- **`flipped`** (exit 0): symlink was atomically updated (temp-and-replace). Continue to §6.
|
|
222
|
+
- **`missing-target`** (exit 2): `{skill_group}/{version}/` directory does not exist on disk. HALT — display `halt_message` verbatim. This indicates §4 §6b did not write the version directory before §5b ran (a workflow bug, not a user error).
|
|
223
|
+
- **`mismatch`** (exit 2): re-read after flip showed the symlink still points elsewhere. HALT — display `halt_message`. Should be impossible because the helper uses `os.replace` (atomic rename); a mismatch here indicates filesystem-level interference (concurrent writer, broken FUSE mount).
|
|
216
224
|
|
|
217
225
|
### 6. Verify Derived Artifact Writes
|
|
218
226
|
|
|
219
|
-
SKILL.md was verified in section 1 and stack reference files in section 5 (both written by step
|
|
227
|
+
SKILL.md was verified in section 1 and stack reference files in section 5 (both written by step 4 section 6b). This section verifies the artifacts this step wrote: `metadata.json`, `provenance-map.json`, `evidence-report.md`, `context-snippet.md`, and the `active` symlink from §5b.
|
|
220
228
|
|
|
221
229
|
For each derived artifact:
|
|
222
230
|
- Read back the file
|
|
223
231
|
- Confirm content matches expected output
|
|
224
232
|
- Report verification status
|
|
225
233
|
|
|
226
|
-
**Active symlink verification:**
|
|
234
|
+
**Active symlink verification:** run `{updateActiveSymlinkHelper} verify --skill-group {skill_group} --version {version}` — read-only check that the symlink resolves to the version just written to `metadata.json` in §2. This closes the §5b gap where a silent skip would otherwise leave the manifest and symlink divergent — the symlink is the fallback resolver for consumers that don't read the manifest (see `knowledge/version-paths.md` §Reading Workflows step 5), so a `mismatch` must fail the step, not warn. Applies in every mode — gap-driven runs do not bump `version`, but the symlink must still point to the current `version`, otherwise a prior partial run left it pointing elsewhere.
|
|
227
235
|
|
|
228
236
|
"**Write Verification:**
|
|
229
237
|
|
|
@@ -237,27 +245,41 @@ For each derived artifact:
|
|
|
237
245
|
| {skill_group}/active symlink | {VERIFIED/FAILED} (readlink → {resolved_version}, expected {version}) |
|
|
238
246
|
| {stack reference files...} | {VERIFIED in section 5} |
|
|
239
247
|
|
|
240
|
-
**On symlink
|
|
248
|
+
**On symlink `mismatch` (helper exit 2):** HALT. Do not proceed to §7 post-write validation or §8 menu. Display the helper's `halt_message` verbatim — it already includes the diverged target, the expected version, and the recovery command. This matches the severity of the other four artifact checks — silent divergence here mis-routes any downstream consumer that uses the symlink fallback.
|
|
241
249
|
|
|
242
250
|
**All files written and verified.**"
|
|
243
251
|
|
|
244
252
|
### 7. Run Post-Write Validation (Deferred from Step 05)
|
|
245
253
|
|
|
246
|
-
External tool checks deferred from step
|
|
254
|
+
External tool checks deferred from step 5 now run against the written files.
|
|
255
|
+
|
|
256
|
+
**Description Guard Protocol:** every invocation below that may modify SKILL.md (`skill-check check --fix` and any `split-body` write) must run inside the four-phase guard defined in §0. Invoke `{descriptionGuardHelper}` at the capture and verify-restore points around each call:
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
# Phase 1 — capture before any frontmatter-touching tool call
|
|
260
|
+
uv run {descriptionGuardHelper} capture {skill_package}/SKILL.md
|
|
261
|
+
# stash returned `description` as `guarded_description`
|
|
262
|
+
|
|
263
|
+
# Phase 2 — run the tool (skill-check --fix, split-body --write, etc.)
|
|
264
|
+
|
|
265
|
+
# Phases 3+4 — verify and restore after the tool call
|
|
266
|
+
uv run {descriptionGuardHelper} verify-restore {skill_package}/SKILL.md \
|
|
267
|
+
--captured-description "{guarded_description}"
|
|
268
|
+
```
|
|
247
269
|
|
|
248
|
-
|
|
270
|
+
Do not rely on per-call ad-hoc preservation logic — use the helper.
|
|
249
271
|
|
|
250
272
|
**If skill-check available:**
|
|
251
273
|
|
|
252
274
|
- Run: `npx skill-check check {skill_package} --fix --format json --no-security-scan` **inside the §0 guard**.
|
|
253
|
-
- **Context sync after --fix:** If `fixed[]` is non-empty (i.e., `--fix` modified files on disk), re-read the modified SKILL.md to update the in-context copy. This prevents silent divergence between the in-context SKILL.md and the on-disk version that
|
|
275
|
+
- **Context sync after --fix:** If `fixed[]` is non-empty (i.e., `--fix` modified files on disk), re-read the modified SKILL.md to update the in-context copy. This prevents silent divergence between the in-context SKILL.md and the on-disk version that report will reference. The §0 guard has already restored `description` if divergent; the re-read picks up any other fix-corrected content.
|
|
254
276
|
- If `body.max_lines` reported, prefer selective split — extract only the largest Tier 2 section(s) to `references/`, keeping Tier 1 inline (inline passive context achieves 100% task accuracy vs 79% for on-demand retrieval). **If falling back to `npx skill-check split-body {skill_package} --write`, run it inside the §0 guard** — split-body can also touch frontmatter. Verify anchors resolve after split.
|
|
255
277
|
- Run: `npx skill-check diff` if original version was preserved.
|
|
256
278
|
- Run: `npx skill-check check {skill_package} --format json` for security scan. (Read-only; guard not required.)
|
|
257
279
|
|
|
258
280
|
Record findings in the evidence report (section 4), including any `description_guard_restored` events recorded by the §0 protocol. These are advisory — do not block on warnings.
|
|
259
281
|
|
|
260
|
-
**If skill-check unavailable:** Skip with note — structural checks from step
|
|
282
|
+
**If skill-check unavailable:** Skip with note — structural checks from step 5 are sufficient.
|
|
261
283
|
|
|
262
284
|
### 8. Present MENU OPTIONS
|
|
263
285
|
|
|
@@ -11,6 +11,14 @@ Cross-references generated skills against architecture and PRD documents to prod
|
|
|
11
11
|
|
|
12
12
|
**Schema contract:** This skill is the PRODUCER of the feasibility report schema defined in `src/shared/references/feasibility-report-schema.md`. All report outputs emit `schemaVersion: "1.0"` in frontmatter, use only the defined verdict tokens (`Verified|Plausible|Risky|Blocked` per pair; `FEASIBLE|CONDITIONALLY_FEASIBLE|NOT_FEASIBLE` overall), follow the fixed section-heading order, and are written through `src/shared/scripts/skf-atomic-write.py write` to both the timestamped file and the stable `-latest.md` copy.
|
|
13
13
|
|
|
14
|
+
## Conventions
|
|
15
|
+
|
|
16
|
+
- Bare paths (e.g. `references/<name>.md`) resolve from the skill root.
|
|
17
|
+
- `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.
|
|
18
|
+
- `{skill-root}` resolves to this skill's installed directory (where `customize.toml` lives, if present).
|
|
19
|
+
- `{project-root}`-prefixed paths resolve from the project working directory.
|
|
20
|
+
- `{skill-name}` resolves to the skill directory's basename.
|
|
21
|
+
|
|
14
22
|
## Role
|
|
15
23
|
|
|
16
24
|
You are a stack feasibility analyst and integration verifier operating in Ferris Audit mode. You bring expertise in API surface analysis, cross-library compatibility assessment, and architecture validation, while the user brings their architecture vision and generated skills.
|
|
@@ -21,40 +29,104 @@ These rules apply to every step in this workflow:
|
|
|
21
29
|
|
|
22
30
|
- Read-only — never modify skills, architecture docs, or PRD files
|
|
23
31
|
- Every verdict must cite evidence from the generated skills
|
|
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
|
- If any instruction references a subprocess or tool you lack, achieve the outcome in your main context thread
|
|
28
34
|
- Always communicate in `{communication_language}`
|
|
35
|
+
- At any interactive prompt, the inputs `cancel`, `exit`, `[X]`, `q`, or `:q` exit cleanly with exit code 6 (`halt_reason: "user-cancelled"`)
|
|
29
36
|
- If `{headless_mode}` is true, auto-proceed through confirmation gates with their default action and log each auto-decision
|
|
30
37
|
|
|
31
38
|
## Stages
|
|
32
39
|
|
|
33
40
|
| # | Step | File | Auto-proceed |
|
|
34
41
|
|---|------|------|--------------|
|
|
35
|
-
| 1 | Initialize & Load Inputs |
|
|
36
|
-
| 2 | Coverage Analysis |
|
|
37
|
-
| 3 | Integration Verification |
|
|
38
|
-
| 4 | Requirements Mapping |
|
|
39
|
-
| 5 | Synthesize Verdict |
|
|
40
|
-
| 6 | Report |
|
|
41
|
-
| 7 | Workflow Health Check |
|
|
42
|
+
| 1 | Initialize & Load Inputs | references/init.md | No (confirm) |
|
|
43
|
+
| 2 | Coverage Analysis | references/coverage.md | Yes |
|
|
44
|
+
| 3 | Integration Verification | references/integrations.md | Yes |
|
|
45
|
+
| 4 | Requirements Mapping | references/requirements.md | Yes |
|
|
46
|
+
| 5 | Synthesize Verdict | references/synthesize.md | Yes |
|
|
47
|
+
| 6 | Report | references/report.md | No (confirm) |
|
|
48
|
+
| 7 | Workflow Health Check | references/health-check.md | Yes |
|
|
42
49
|
|
|
43
50
|
## Invocation Contract
|
|
44
51
|
|
|
45
52
|
| Aspect | Detail |
|
|
46
53
|
|--------|--------|
|
|
47
|
-
| **Inputs** | architecture_doc_path [required], prd_path [optional] |
|
|
48
|
-
| **
|
|
49
|
-
| **
|
|
50
|
-
| **
|
|
54
|
+
| **Inputs** | architecture_doc_path [required], prd_path [optional], previous_report_path [optional] |
|
|
55
|
+
| **Flags** | `--headless` / `-H` (auto-resolve all gates); `--architecture-doc <path>` (skip step 1 prompt for the required input); `--prd <path>` (skip step 1 prompt for the optional PRD); `--previous-report <path>` (skip step 1 prompt for delta comparison) |
|
|
56
|
+
| **Gates** | step 1: Input Gate [use args] | step 6: Confirm Gate [C] |
|
|
57
|
+
| **Outputs** | `feasibility-report-{projectSlug}-{timestamp}.md` and `feasibility-report-{projectSlug}-latest.md` (copy, not symlink) per `src/shared/references/feasibility-report-schema.md` — with integration verdicts, coverage analysis, recommendations, and evidence sources; plus `verify-stack-result-{timestamp}.json` and `verify-stack-result-latest.json` |
|
|
58
|
+
| **Headless** | All gates auto-resolve with default action when `{headless_mode}` is true. Per-flag args (`--architecture-doc`, `--prd`, `--previous-report`) consumed at the gates that would otherwise prompt. |
|
|
59
|
+
| **Exit codes** | See "Exit Codes" below |
|
|
60
|
+
|
|
61
|
+
## Exit Codes
|
|
62
|
+
|
|
63
|
+
Every HARD HALT in this workflow exits with a stable code so headless automators can branch on the failure class without grepping message text:
|
|
64
|
+
|
|
65
|
+
| Code | Meaning | Raised by |
|
|
66
|
+
| ---- | -------------------- | -------------------------------------------------------------------------------------------- |
|
|
67
|
+
| 0 | success | step 7 (terminal) |
|
|
68
|
+
| 2 | input-missing / input-invalid | step 1 §1 (headless missing `architecture-doc` arg, or invalid path) → `input-missing`; non-existent file → `input-invalid` |
|
|
69
|
+
| 3 | resolution-failure | step 1 §2 (`{skills_output_folder}` does not exist or is empty); step 1 §3 (forge_data_folder unconfigured) |
|
|
70
|
+
| 4 | write-failure | On-Activation §3 pre-flight write probe; step 1 §4 (atomic write of report skeleton failed); step 6 §4b (result-contract write failed) |
|
|
71
|
+
| 5 | state-conflict | step 1 §3 (fewer than 2 valid skills found — stack requires ≥2); step 1 §1 (`previousReport` resolves to same inode as `{outputFile}`); step 6 §1 (report section order or schemaVersion mismatch — schema-violation) |
|
|
72
|
+
| 6 | user-cancelled | step 1 §1 prompt cancelled; any prompt that accepted `cancel`/`exit`/`:q`; step 6 menu cancelled |
|
|
73
|
+
| 7 | inventory-unreliable | step 1 §2 (>20% subagent failures or enumerate-stack-skills warnings exceed budget) |
|
|
74
|
+
|
|
75
|
+
## Result Contract (Headless)
|
|
76
|
+
|
|
77
|
+
When `{headless_mode}` is true, step 6 emits a single-line JSON envelope on **stdout** before chaining to step 7, and every HARD HALT emits the same envelope shape on **stderr** with `status: "error"`:
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
SKF_VERIFY_STACK_RESULT_JSON: {"status":"success|error","report_path":"…|null","report_latest_path":"…|null","overall_verdict":"…|null","coverage_percentage":0,"recommendation_count":0,"exit_code":0,"halt_reason":null}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
`status` is `"success"` on the terminal happy path, `"error"` on any HALT. `halt_reason` is one of: `null` (success), `"input-missing"`, `"input-invalid"`, `"skills-folder-missing"`, `"insufficient-skills"`, `"forge-folder-unconfigured"`, `"previous-report-collision"`, `"inventory-unreliable"`, `"schema-violation"`, `"write-failed"`, `"user-cancelled"`. `exit_code` matches the table above. `overall_verdict` uses the schema tokens (`FEASIBLE`/`CONDITIONALLY_FEASIBLE`/`NOT_FEASIBLE`).
|
|
51
84
|
|
|
52
85
|
## On Activation
|
|
53
86
|
|
|
54
87
|
1. Load config from `{project-root}/_bmad/skf/config.yaml` and resolve:
|
|
55
|
-
- `project_name`, `user_name`, `communication_language`
|
|
56
|
-
- `skills_output_folder`, `forge_data_folder`, `
|
|
88
|
+
- `project_name`, `user_name`, `communication_language`, `document_output_language`
|
|
89
|
+
- `skills_output_folder`, `forge_data_folder`, `sidecar_path`
|
|
90
|
+
|
|
91
|
+
2. **Compute run-scoped variables** (same place as config so every stage can reference them without re-derivation):
|
|
92
|
+
- `project_slug` ← slugify `project_name` (lowercase, hyphens only, no unicode, no whitespace)
|
|
93
|
+
- `timestamp` ← UTC `YYYYMMDD-HHmmss` captured at activation time
|
|
94
|
+
- These two combine in init.md §4 into `{outputFile}` per the stage frontmatter template, but the values themselves are fixed for the entire workflow run — every later reference to `{outputFile}` resolves consistently. (Computing them here resolves an order-of-operations bug where the §1 §3 inode-collision check referenced `{outputFile}` before `{project_slug}` and `{timestamp}` were defined.)
|
|
95
|
+
|
|
96
|
+
3. **Resolve `{headless_mode}`**: true if `--headless` or `-H` was passed as an argument, or if `headless_mode: true` in `{sidecar_path}/preferences.yaml`. Default: false.
|
|
97
|
+
|
|
98
|
+
4. **Resolve workflow customization.** Run:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
python3 {project-root}/_bmad/scripts/resolve_customization.py \
|
|
102
|
+
--skill {skill-root} --key workflow
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
The script merges the three customization layers per `bmad-customize`'s structural merge rules (scalars override, arrays append):
|
|
106
|
+
|
|
107
|
+
- `{skill-root}/customize.toml` — bundled defaults
|
|
108
|
+
- `_bmad/custom/<skill-name>.toml` under `{project-root}` — team overrides (committed)
|
|
109
|
+
- `_bmad/custom/<skill-name>.user.toml` under `{project-root}` — personal overrides (gitignored)
|
|
110
|
+
|
|
111
|
+
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.
|
|
112
|
+
|
|
113
|
+
Apply the path-scalar fallback now so stage files don't have to repeat the conditional logic. For each of the four scalars, if the merged value is empty or absent, use the bundled default:
|
|
114
|
+
|
|
115
|
+
- `{reportTemplatePath}` ← `workflow.report_template_path` if non-empty, else `assets/feasibility-report-template.md`
|
|
116
|
+
- `{integrationRulesPath}` ← `workflow.integration_rules_path` if non-empty, else `references/integration-verification-rules.md`
|
|
117
|
+
- `{coveragePatternsPath}` ← `workflow.coverage_patterns_path` if non-empty, else `references/coverage-patterns.md`
|
|
118
|
+
- `{outputFolderPath}` ← `workflow.output_folder_path` if non-empty, else `{forge_data_folder}`
|
|
119
|
+
|
|
120
|
+
Stash all four as workflow-context variables. Stage files reference them directly — no conditional at the usage site. Empty-string overrides cleanly fall through to the bundled default.
|
|
121
|
+
|
|
122
|
+
5. **Pre-flight write probe.** Verify `{outputFolderPath}` is writable. A read-only mount, full disk, or permissions-denied path otherwise only surfaces at init.md §4 atomic write — by then the user has already gone through the input prompts:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
mkdir -p "{outputFolderPath}" && \
|
|
126
|
+
printf 'probe' > "{outputFolderPath}/.skf-write-probe" && \
|
|
127
|
+
rm "{outputFolderPath}/.skf-write-probe"
|
|
128
|
+
```
|
|
57
129
|
|
|
58
|
-
|
|
130
|
+
On any non-zero exit: HALT (exit code 4, `halt_reason: "write-failed"`). In headless mode, emit the error envelope per **Result Contract (Headless)** with `report_path: null`, `report_latest_path: null`, `overall_verdict: null`.
|
|
59
131
|
|
|
60
|
-
|
|
132
|
+
6. Load, read the full file, and then execute `references/init.md` to begin the workflow.
|
|
@@ -49,13 +49,13 @@ deltaUnchanged: null
|
|
|
49
49
|
|
|
50
50
|
## Coverage Analysis
|
|
51
51
|
|
|
52
|
-
<!-- Appended by
|
|
52
|
+
<!-- Appended by coverage -->
|
|
53
53
|
|
|
54
54
|
---
|
|
55
55
|
|
|
56
56
|
## Integration Verdicts
|
|
57
57
|
|
|
58
|
-
<!-- Appended by
|
|
58
|
+
<!-- Appended by integrations.
|
|
59
59
|
Consumers grep for the `## Integration Verdicts` heading to locate the pair table.
|
|
60
60
|
The table header is fixed and MUST be emitted exactly as shown below: -->
|
|
61
61
|
|
|
@@ -66,11 +66,11 @@ The table header is fixed and MUST be emitted exactly as shown below: -->
|
|
|
66
66
|
|
|
67
67
|
## Recommendations
|
|
68
68
|
|
|
69
|
-
<!-- Appended by
|
|
69
|
+
<!-- Appended by synthesize -->
|
|
70
70
|
|
|
71
71
|
---
|
|
72
72
|
|
|
73
73
|
## Evidence Sources
|
|
74
74
|
|
|
75
|
-
<!-- Appended by
|
|
75
|
+
<!-- Appended by synthesize — cite each skill's SKILL.md path, metadata_schema_version,
|
|
76
76
|
confidence_tier, stack manifest (if any), and architecture/PRD doc paths -->
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# DO NOT EDIT -- overwritten on every update.
|
|
2
|
+
#
|
|
3
|
+
# Workflow customization surface for skf-verify-stack.
|
|
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 verification 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
|
+
# (verification standards, evidence-citation rules, house-style verdict
|
|
25
|
+
# language). Overrides append.
|
|
26
|
+
#
|
|
27
|
+
# Each entry is either:
|
|
28
|
+
# - a literal sentence, e.g. "Verdict citations must include file:line spans."
|
|
29
|
+
# - a file reference prefixed with `file:`, e.g.
|
|
30
|
+
# "file:{project-root}/docs/verify-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
|
+
]
|
|
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
|
+
report_template_path = ""
|
|
43
|
+
integration_rules_path = ""
|
|
44
|
+
coverage_patterns_path = ""
|
|
45
|
+
|
|
46
|
+
# Override the destination directory for the feasibility report. Empty =
|
|
47
|
+
# use {forge_data_folder} from config.yaml. Useful for orgs that want
|
|
48
|
+
# verification artifacts to land outside the per-skill forge tree.
|
|
49
|
+
|
|
50
|
+
output_folder_path = ""
|
|
@@ -26,14 +26,14 @@ Parse document section headers for technology groupings:
|
|
|
26
26
|
|
|
27
27
|
### Coverage Verdict
|
|
28
28
|
|
|
29
|
-
The coverage matrix renders two verdict tokens per referenced technology: **Covered** and **Missing**. Extra skills (skills present in the inventory but NOT referenced by the architecture document) are tracked in a separate informational subdivision — they are not coverage verdicts and do not appear in the primary `Technology → Skill Match → Verdict` column. See step
|
|
29
|
+
The coverage matrix renders two verdict tokens per referenced technology: **Covered** and **Missing**. Extra skills (skills present in the inventory but NOT referenced by the architecture document) are tracked in a separate informational subdivision — they are not coverage verdicts and do not appear in the primary `Technology → Skill Match → Verdict` column. See step 2 §4 for the Extra-skill subdivision output.
|
|
30
30
|
|
|
31
31
|
| Verdict | Meaning |
|
|
32
32
|
|-------------|------------------------------------------------------------------|
|
|
33
33
|
| **Covered** | A generated skill exists in `skills/` for this technology |
|
|
34
34
|
| **Missing** | Technology is referenced in architecture doc but no skill exists |
|
|
35
35
|
|
|
36
|
-
**Informational — Extra skills subdivision (not a verdict; rendered in a separate section per step
|
|
36
|
+
**Informational — Extra skills subdivision (not a verdict; rendered in a separate section per step 2 §4):**
|
|
37
37
|
|
|
38
38
|
| Label | Meaning |
|
|
39
39
|
|----------------------------------------|----------------------------------------------------------------------------------------------------------------------------------|
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
---
|
|
2
|
-
nextStepFile: '
|
|
3
|
-
coveragePatternsData: '
|
|
2
|
+
nextStepFile: 'integrations.md'
|
|
3
|
+
coveragePatternsData: '{coveragePatternsPath}'
|
|
4
4
|
feasibilitySchemaRef: 'src/shared/references/feasibility-report-schema.md'
|
|
5
5
|
atomicWriteScript: '{project-root}/src/shared/scripts/skf-atomic-write.py'
|
|
6
|
-
outputFile: '{
|
|
7
|
-
outputFileLatest: '{
|
|
6
|
+
outputFile: '{outputFolderPath}/feasibility-report-{project_slug}-{timestamp}.md'
|
|
7
|
+
outputFileLatest: '{outputFolderPath}/feasibility-report-{project_slug}-latest.md'
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
<!-- Config: communicate in {communication_language}. Append the Coverage Analysis section to the report in {document_output_language}. -->
|
|
11
|
+
|
|
10
12
|
# Step 2: Technology Coverage Analysis
|
|
11
13
|
|
|
12
14
|
## STEP GOAL:
|
|
@@ -20,8 +22,6 @@ Verify that a generated skill exists for every technology, library, or framework
|
|
|
20
22
|
|
|
21
23
|
## MANDATORY SEQUENCE
|
|
22
24
|
|
|
23
|
-
**CRITICAL:** Follow this sequence exactly. Do not skip, reorder, or improvise.
|
|
24
|
-
|
|
25
25
|
### 1. Load Coverage Patterns
|
|
26
26
|
|
|
27
27
|
Load `{coveragePatternsData}` for detection rules.
|
|
@@ -112,7 +112,7 @@ Write the **Coverage Analysis** section to `{outputFile}` (see `{feasibilitySche
|
|
|
112
112
|
- Include coverage percentage
|
|
113
113
|
- Include missing skill recommendations
|
|
114
114
|
- Include the Extra (unreferenced) and Orphan (source_repo unresolvable) subdivisions from section 4
|
|
115
|
-
- Update frontmatter: append `'
|
|
115
|
+
- Update frontmatter: append `'coverage'` to `stepsCompleted`; set `coveragePercentage` (integer 0..100)
|
|
116
116
|
- Pipe the updated full content through `python3 {atomicWriteScript} write --target {outputFile}` and again with `--target {outputFileLatest}`
|
|
117
117
|
|
|
118
118
|
### 7. Auto-Proceed to Next Step
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
---
|
|
2
|
-
# `shared/health-check.md` resolves relative to the SKF module root
|
|
3
|
-
# (
|
|
4
|
-
# to this step file.
|
|
2
|
+
# Note: `shared/health-check.md` resolves relative to the SKF module root
|
|
3
|
+
# ({project-root}/_bmad/skf/ when installed, {project-root}/src/ during
|
|
4
|
+
# development), NOT relative to this step file.
|
|
5
5
|
nextStepFile: 'shared/health-check.md'
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
+
<!-- Config: communicate in {communication_language}. -->
|
|
9
|
+
|
|
8
10
|
# Step 7: Workflow Health Check
|
|
9
11
|
|
|
10
12
|
## STEP GOAL:
|
|
@@ -13,7 +15,7 @@ Chain to the shared workflow self-improvement health check at `{nextStepFile}`.
|
|
|
13
15
|
|
|
14
16
|
## Rules
|
|
15
17
|
|
|
16
|
-
- No user-facing reports, file writes, or result contracts in this step — those belong in step
|
|
18
|
+
- No user-facing reports, file writes, or result contracts in this step — those belong in step 6
|
|
17
19
|
- Delegate directly to `{nextStepFile}` with no additional commentary
|
|
18
20
|
- Do not attempt any other action between loading this step and executing `{nextStepFile}`
|
|
19
21
|
|
|
@@ -22,4 +24,4 @@ Chain to the shared workflow self-improvement health check at `{nextStepFile}`.
|
|
|
22
24
|
Attempt to load `{nextStepFile}`.
|
|
23
25
|
|
|
24
26
|
- **If `{nextStepFile}` loads successfully:** Read it fully, then execute it.
|
|
25
|
-
- **If `{nextStepFile}` cannot be resolved or loaded** (e.g., running against a partial installation, module root not resolvable, or the file has been removed): log exactly `health-check unavailable at {path}` (substitute the attempted resolved path) to the user-visible output and exit the workflow cleanly. Do NOT HALT with an error — the health check is an optional self-improvement hook, and the feasibility report (written in step
|
|
27
|
+
- **If `{nextStepFile}` cannot be resolved or loaded** (e.g., running against a partial installation, module root not resolvable, or the file has been removed): log exactly `health-check unavailable at {path}` (substitute the attempted resolved path) to the user-visible output and exit the workflow cleanly. Do NOT HALT with an error — the health check is an optional self-improvement hook, and the feasibility report (written in step 6) is the authoritative workflow output. Exit cleanly so CI and headless runs do not fail on a missing optional hook.
|