bmad-module-skill-forge 1.9.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/.nvmrc +1 -1
- package/README.md +10 -5
- package/docs/_data/pinned.yaml +2 -2
- package/docs/agents.md +11 -2
- package/docs/architecture.md +5 -4
- package/docs/bmad-synergy.md +30 -7
- package/docs/campaign.md +172 -0
- package/docs/examples.md +7 -3
- package/docs/forge-auto.md +90 -0
- package/docs/getting-started.md +9 -0
- package/docs/how-it-works.md +6 -4
- package/docs/index.md +4 -3
- package/docs/skill-model.md +1 -1
- package/docs/troubleshooting.md +17 -1
- package/docs/verifying-a-skill.md +2 -2
- package/docs/why-skf.md +1 -1
- package/docs/workflows.md +64 -24
- package/package.json +2 -2
- package/src/knowledge/skill-lifecycle.md +1 -1
- package/src/module-help.csv +4 -3
- package/src/shared/data/language-corpora.json +32 -0
- package/src/shared/references/pipeline-contracts.md +6 -3
- package/src/shared/scripts/schemas/skill-brief.v1.json +6 -1
- package/src/shared/scripts/skf-comention-pairs.py +350 -0
- package/src/shared/scripts/skf-count-tokens.py +222 -0
- package/src/shared/scripts/skf-derive-assembly-shape.py +107 -0
- package/src/shared/scripts/skf-detect-docs.py +240 -4
- package/src/shared/scripts/skf-detect-language.py +82 -3
- package/src/shared/scripts/skf-detect-tools.py +105 -2
- package/src/shared/scripts/skf-emit-result-envelope.py +17 -0
- package/src/shared/scripts/skf-enumerate-stack-skills.py +111 -2
- package/src/shared/scripts/skf-extract-public-api.py +53 -0
- package/src/shared/scripts/skf-find-cycles.py +246 -0
- package/src/shared/scripts/skf-hash-content.py +487 -2
- package/src/shared/scripts/skf-language-corpora.py +100 -0
- package/src/shared/scripts/skf-manifest-ops.py +67 -1
- package/src/shared/scripts/skf-merge-doc-urls.py +244 -0
- package/src/shared/scripts/skf-preapply.py +1 -1
- package/src/shared/scripts/skf-rebuild-managed-sections.py +180 -0
- package/src/shared/scripts/skf-recommend-scope-type.py +1 -2
- package/src/shared/scripts/skf-render-metadata-stats.py +499 -0
- package/src/shared/scripts/skf-rewrite-skill-name.py +308 -0
- package/src/shared/scripts/skf-shape-detect.py +576 -25
- package/src/shared/scripts/skf-shard-body.py +461 -0
- package/src/shared/scripts/skf-skill-inventory.py +139 -3
- package/src/shared/scripts/skf-structural-diff.py +307 -67
- package/src/shared/scripts/skf-validate-brief-schema.py +41 -6
- package/src/shared/scripts/skf-validate-feasibility-report.py +234 -0
- package/src/shared/scripts/skf-validate-frontmatter.py +17 -12
- package/src/shared/scripts/skf-validate-output.py +443 -10
- package/src/shared/scripts/skf-validate-pins.py +3 -3
- package/src/shared/scripts/skf-verify-no-trace.py +214 -0
- package/src/shared/scripts/skf-verify-provenance-completeness.py +439 -0
- package/src/shared/scripts/skf-write-skill-brief.py +21 -5
- package/src/skf-analyze-source/SKILL.md +17 -32
- package/src/skf-analyze-source/assets/skill-brief-schema.md +1 -1
- package/src/skf-analyze-source/customize.toml +2 -0
- package/src/skf-analyze-source/references/auto-docs-only.md +116 -0
- package/src/skf-analyze-source/references/continue.md +8 -13
- package/src/skf-analyze-source/references/generate-briefs.md +28 -12
- package/src/skf-analyze-source/references/headless-contract.md +33 -0
- package/src/skf-analyze-source/references/health-check.md +1 -2
- package/src/skf-analyze-source/references/identify-units.md +25 -36
- package/src/skf-analyze-source/references/init.md +12 -25
- package/src/skf-analyze-source/references/map-and-detect.md +8 -20
- package/src/skf-analyze-source/references/recommend.md +4 -14
- package/src/skf-analyze-source/references/scan-project.md +3 -11
- package/src/skf-analyze-source/references/step-auto-scope.md +211 -197
- package/src/skf-analyze-source/references/step-shape-detect.md +20 -13
- package/src/skf-analyze-source/references/unit-detection-heuristics.md +2 -2
- package/src/skf-audit-skill/SKILL.md +9 -6
- package/src/skf-audit-skill/customize.toml +2 -0
- package/src/skf-audit-skill/references/init.md +58 -32
- package/src/skf-audit-skill/references/re-index.md +15 -34
- package/src/skf-audit-skill/references/report.md +11 -58
- package/src/skf-audit-skill/references/semantic-diff.md +4 -22
- package/src/skf-audit-skill/references/severity-classify.md +53 -87
- package/src/skf-audit-skill/references/step-doc-drift.md +49 -19
- package/src/skf-audit-skill/references/structural-diff.md +43 -68
- package/src/skf-brief-skill/SKILL.md +7 -36
- package/src/skf-brief-skill/assets/scope-templates.md +1 -1
- package/src/skf-brief-skill/assets/skill-brief-schema.md +1 -1
- package/src/skf-brief-skill/customize.toml +14 -0
- package/src/skf-brief-skill/references/analyze-target.md +13 -18
- package/src/skf-brief-skill/references/confirm-brief.md +2 -15
- package/src/skf-brief-skill/references/draft-checkpoint.md +8 -8
- package/src/skf-brief-skill/references/gather-intent.md +27 -24
- package/src/skf-brief-skill/references/headless-args.md +1 -1
- package/src/skf-brief-skill/references/health-check.md +1 -22
- package/src/skf-brief-skill/references/invocation-contract.md +37 -0
- package/src/skf-brief-skill/references/scope-definition.md +6 -15
- package/src/skf-brief-skill/references/step-auto-brief.md +22 -9
- package/src/skf-brief-skill/references/step-auto-validate.md +3 -7
- package/src/skf-brief-skill/references/version-resolution.md +1 -1
- package/src/skf-brief-skill/references/write-brief.md +19 -13
- package/src/skf-campaign/SKILL.md +121 -0
- package/src/skf-campaign/assets/campaign-state-schema.json +191 -0
- package/src/skf-campaign/customize.toml +75 -0
- package/src/skf-campaign/manifest.yaml +15 -0
- package/src/skf-campaign/references/campaign-contracts.md +67 -0
- package/src/skf-campaign/references/campaign-directive-spec.md +32 -0
- package/src/skf-campaign/references/health-check.md +35 -0
- package/src/skf-campaign/references/step-01-setup.md +121 -0
- package/src/skf-campaign/references/step-02-strategy.md +102 -0
- package/src/skf-campaign/references/step-03-pins.md +56 -0
- package/src/skf-campaign/references/step-04-provenance.md +63 -0
- package/src/skf-campaign/references/step-05-skill-loop.md +103 -0
- package/src/skf-campaign/references/step-06-batch.md +88 -0
- package/src/skf-campaign/references/step-07-capstone.md +63 -0
- package/src/skf-campaign/references/step-08-verify.md +75 -0
- package/src/skf-campaign/references/step-09-refine.md +83 -0
- package/src/skf-campaign/references/step-10-export.md +106 -0
- package/src/skf-campaign/references/step-11-maintenance.md +84 -0
- package/src/skf-campaign/references/step-resume.md +115 -0
- package/src/skf-campaign/scripts/.gitkeep +0 -0
- package/src/skf-campaign/scripts/campaign-deps.py +244 -0
- package/src/skf-campaign/scripts/campaign-parse-manifest.py +119 -0
- package/src/skf-campaign/scripts/campaign-provenance.py +247 -0
- package/src/skf-campaign/scripts/campaign-render-batch.py +199 -0
- package/src/skf-campaign/scripts/campaign-render-kickoff.py +158 -0
- package/src/skf-campaign/scripts/campaign-report.py +249 -0
- package/src/skf-campaign/scripts/campaign-status.py +162 -0
- package/src/skf-campaign/scripts/campaign-validate-pins.py +174 -0
- package/src/skf-campaign/scripts/campaign-validate-state.py +207 -0
- package/src/skf-campaign/templates/campaign-brief-template.yaml +34 -0
- package/src/skf-campaign/templates/campaign-report-template.md +54 -0
- package/src/skf-campaign/templates/kickoff-template.md +48 -0
- package/src/skf-create-skill/SKILL.md +15 -4
- package/src/skf-create-skill/assets/compile-assembly-rules.md +35 -34
- package/src/skf-create-skill/assets/skill-sections.md +9 -100
- package/src/skf-create-skill/assets/tessl-dismissal-rules.md +4 -13
- package/src/skf-create-skill/customize.toml +13 -0
- package/src/skf-create-skill/references/authoritative-files-protocol.md +7 -7
- package/src/skf-create-skill/references/compile.md +37 -47
- package/src/skf-create-skill/references/component-extraction.md +8 -35
- package/src/skf-create-skill/references/ecosystem-check.md +9 -25
- package/src/skf-create-skill/references/enrich.md +4 -17
- package/src/skf-create-skill/references/extract.md +20 -27
- package/src/skf-create-skill/references/extraction-patterns-tracing.md +1 -1
- package/src/skf-create-skill/references/extraction-patterns.md +10 -8
- package/src/skf-create-skill/references/generate-artifacts.md +20 -25
- package/src/skf-create-skill/references/health-check.md +2 -2
- package/src/skf-create-skill/references/load-brief.md +16 -18
- package/src/skf-create-skill/references/report.md +27 -14
- package/src/skf-create-skill/references/source-resolution-protocols.md +4 -4
- package/src/skf-create-skill/references/step-auto-shard.md +52 -25
- package/src/skf-create-skill/references/step-doc-rot.md +33 -15
- package/src/skf-create-skill/references/step-doc-sources.md +13 -4
- package/src/skf-create-skill/references/sub/ccc-discover.md +2 -13
- package/src/skf-create-skill/references/sub/fetch-docs.md +33 -46
- package/src/skf-create-skill/references/sub/fetch-temporal.md +5 -20
- package/src/skf-create-skill/references/tier-degradation-rules.md +6 -8
- package/src/skf-create-skill/references/validate.md +69 -29
- package/src/skf-create-skill/scripts/scan-doc-rot.py +245 -0
- package/src/skf-create-stack-skill/SKILL.md +15 -9
- package/src/skf-create-stack-skill/assets/provenance-map-schema.md +1 -1
- package/src/skf-create-stack-skill/customize.toml +10 -0
- package/src/skf-create-stack-skill/references/compile-stack.md +7 -8
- package/src/skf-create-stack-skill/references/compose-mode-rules.md +2 -13
- package/src/skf-create-stack-skill/references/detect-integrations.md +49 -54
- package/src/skf-create-stack-skill/references/detect-manifests.md +37 -30
- package/src/skf-create-stack-skill/references/generate-output.md +24 -75
- package/src/skf-create-stack-skill/references/init.md +9 -81
- package/src/skf-create-stack-skill/references/manifest-patterns.md +5 -35
- package/src/skf-create-stack-skill/references/parallel-extract.md +12 -27
- package/src/skf-create-stack-skill/references/rank-and-confirm.md +6 -6
- package/src/skf-create-stack-skill/references/report.md +27 -62
- package/src/skf-create-stack-skill/references/validate.md +35 -31
- package/src/skf-drop-skill/SKILL.md +20 -23
- package/src/skf-drop-skill/customize.toml +10 -0
- package/src/skf-drop-skill/references/execute.md +67 -36
- package/src/skf-drop-skill/references/headless-contract.md +18 -0
- package/src/skf-drop-skill/references/health-check.md +1 -13
- package/src/skf-drop-skill/references/report.md +44 -10
- package/src/skf-drop-skill/references/select.md +93 -48
- package/src/skf-drop-skill/scripts/dir-sizes.py +116 -0
- package/src/skf-export-skill/SKILL.md +17 -14
- package/src/skf-export-skill/assets/managed-section-format.md +2 -5
- package/src/skf-export-skill/customize.toml +10 -6
- package/src/skf-export-skill/references/generate-snippet.md +21 -35
- package/src/skf-export-skill/references/load-skill.md +44 -42
- package/src/skf-export-skill/references/multi-skill-mode.md +1 -1
- package/src/skf-export-skill/references/orphan-context-detection.md +11 -3
- package/src/skf-export-skill/references/package.md +27 -33
- package/src/skf-export-skill/references/preflight-snippet-root-probe.md +24 -5
- package/src/skf-export-skill/references/result-envelope.md +28 -0
- package/src/skf-export-skill/references/summary.md +11 -5
- package/src/skf-export-skill/references/token-report.md +42 -24
- package/src/skf-export-skill/references/update-context.md +32 -33
- package/src/skf-forger/SKILL.md +32 -39
- package/src/skf-forger/references/pipeline-mode.md +34 -0
- package/src/skf-forger/scripts/parse-pipeline.py +270 -0
- package/src/skf-quick-skill/SKILL.md +10 -60
- package/src/skf-quick-skill/customize.toml +9 -0
- package/src/skf-quick-skill/references/batch-mode.md +6 -4
- package/src/skf-quick-skill/references/compile.md +15 -52
- package/src/skf-quick-skill/references/ecosystem-check.md +5 -20
- package/src/skf-quick-skill/references/finalize.md +12 -6
- package/src/skf-quick-skill/references/halt-contract.md +54 -0
- package/src/skf-quick-skill/references/health-check.md +3 -4
- package/src/skf-quick-skill/references/quick-extract.md +7 -18
- package/src/skf-quick-skill/references/registry-resolution.md +1 -23
- package/src/skf-quick-skill/references/resolve-target.md +27 -34
- package/src/skf-quick-skill/references/write-and-validate.md +10 -25
- package/src/skf-refine-architecture/SKILL.md +16 -8
- package/src/skf-refine-architecture/customize.toml +9 -0
- package/src/skf-refine-architecture/references/compile.md +10 -8
- package/src/skf-refine-architecture/references/gap-analysis.md +21 -50
- package/src/skf-refine-architecture/references/health-check.md +1 -1
- package/src/skf-refine-architecture/references/improvements.md +9 -25
- package/src/skf-refine-architecture/references/init.md +9 -16
- package/src/skf-refine-architecture/references/issue-detection.md +10 -25
- package/src/skf-refine-architecture/references/refinement-rules.md +4 -16
- package/src/skf-refine-architecture/references/report.md +14 -11
- package/src/skf-rename-skill/SKILL.md +11 -21
- package/src/skf-rename-skill/customize.toml +10 -0
- package/src/skf-rename-skill/references/execute.md +112 -82
- package/src/skf-rename-skill/references/exit-codes.md +12 -0
- package/src/skf-rename-skill/references/report.md +16 -8
- package/src/skf-rename-skill/references/select.md +69 -42
- package/src/skf-rename-skill/scripts/skf-validate-rename-name.py +161 -0
- package/src/skf-setup/SKILL.md +21 -13
- package/src/skf-setup/customize.toml +10 -0
- package/src/skf-setup/references/auto-index.md +11 -10
- package/src/skf-setup/references/ccc-index.md +14 -15
- package/src/skf-setup/references/detect-and-tier.md +10 -8
- package/src/skf-setup/references/report.md +26 -32
- package/src/skf-setup/references/tier-rules.md +2 -32
- package/src/skf-setup/references/write-config.md +9 -10
- package/src/skf-test-skill/SKILL.md +10 -8
- package/src/skf-test-skill/customize.toml +2 -0
- package/src/skf-test-skill/references/coherence-check.md +19 -31
- package/src/skf-test-skill/references/coverage-check.md +111 -67
- package/src/skf-test-skill/references/detect-mode.md +10 -41
- package/src/skf-test-skill/references/external-validators.md +11 -19
- package/src/skf-test-skill/references/init.md +39 -21
- package/src/skf-test-skill/references/migration-section-rules.md +4 -4
- package/src/skf-test-skill/references/report.md +60 -40
- package/src/skf-test-skill/references/score.md +32 -64
- package/src/skf-test-skill/references/scoring-rules.md +6 -62
- package/src/skf-test-skill/references/source-access-protocol.md +15 -5
- package/src/skf-test-skill/references/step-hard-gate.md +1 -3
- package/src/skf-test-skill/scripts/aggregate-coherence.py +276 -0
- package/src/skf-test-skill/scripts/check-metadata-coherence.py +359 -0
- package/src/skf-test-skill/scripts/combine-external-scores.py +190 -0
- package/src/skf-test-skill/scripts/compute-score.py +135 -4
- package/src/skf-test-skill/scripts/reconcile-coverage.py +327 -0
- package/src/skf-test-skill/scripts/validate-inventory.py +251 -0
- package/src/skf-test-skill/scripts/verify-declared-numerator.py +192 -0
- package/src/skf-update-skill/SKILL.md +17 -5
- package/src/skf-update-skill/customize.toml +11 -6
- package/src/skf-update-skill/references/detect-changes.md +48 -36
- package/src/skf-update-skill/references/health-check.md +5 -11
- package/src/skf-update-skill/references/init.md +40 -32
- package/src/skf-update-skill/references/manual-section-rules.md +1 -2
- package/src/skf-update-skill/references/merge-conflict-rules.md +1 -52
- package/src/skf-update-skill/references/merge.md +13 -57
- package/src/skf-update-skill/references/re-extract.md +27 -25
- package/src/skf-update-skill/references/report.md +14 -7
- package/src/skf-update-skill/references/validate.md +32 -30
- package/src/skf-update-skill/references/write.md +86 -51
- package/src/skf-update-skill/scripts/skf-new-file-diff.py +167 -0
- package/src/skf-verify-stack/SKILL.md +11 -21
- package/src/skf-verify-stack/customize.toml +12 -3
- package/src/skf-verify-stack/references/coverage-patterns.md +1 -29
- package/src/skf-verify-stack/references/coverage.md +21 -10
- package/src/skf-verify-stack/references/exit-codes.md +14 -0
- package/src/skf-verify-stack/references/health-check.md +1 -1
- package/src/skf-verify-stack/references/init.md +20 -25
- package/src/skf-verify-stack/references/integration-verification-rules.md +10 -19
- package/src/skf-verify-stack/references/integrations.md +44 -49
- package/src/skf-verify-stack/references/report.md +28 -34
- package/src/skf-verify-stack/references/requirements.md +3 -3
- package/src/skf-verify-stack/references/synthesize.md +36 -39
- package/src/skf-verify-stack/scripts/skf-coverage-tally.py +196 -0
- package/src/skf-verify-stack/scripts/skf-report-delta.py +256 -0
- package/src/skf-verify-stack/scripts/skf-verdict-rollup.py +258 -0
- package/tools/cli/lib/ui.js +3 -2
- package/docs/deepwiki.md +0 -89
- package/src/skf-rename-skill/references/rebuild-context.md +0 -110
|
@@ -8,6 +8,9 @@ feasibilitySchemaProbeOrder:
|
|
|
8
8
|
atomicWriteProbeOrder:
|
|
9
9
|
- '{project-root}/_bmad/skf/shared/scripts/skf-atomic-write.py'
|
|
10
10
|
- '{project-root}/src/shared/scripts/skf-atomic-write.py'
|
|
11
|
+
cycleFinderProbeOrder:
|
|
12
|
+
- '{project-root}/_bmad/skf/shared/scripts/skf-find-cycles.py'
|
|
13
|
+
- '{project-root}/src/shared/scripts/skf-find-cycles.py'
|
|
11
14
|
outputFile: '{outputFolderPath}/feasibility-report-{project_slug}-{timestamp}.md'
|
|
12
15
|
outputFileLatest: '{outputFolderPath}/feasibility-report-{project_slug}-latest.md'
|
|
13
16
|
---
|
|
@@ -48,7 +51,7 @@ Parse the architecture document for statements describing two or more technologi
|
|
|
48
51
|
- Look for data flow descriptions: "{A} sends data to {B}", "{A} results are consumed by {B}"
|
|
49
52
|
- Look for layer boundary descriptions: "{A} at the API layer connects to {B} at the data layer"
|
|
50
53
|
|
|
51
|
-
**
|
|
54
|
+
**Mermaid Diagram Handling:** See `{coveragePatternsData}` → "Mermaid Diagram Handling" for the canonical rule (single source of truth). Summary: do not parse Mermaid diagram syntax for co-mention detection; use only prose text.
|
|
52
55
|
|
|
53
56
|
**Build integration pairs list:**
|
|
54
57
|
- Each pair: `{library_a, library_b, architectural_context}`
|
|
@@ -60,10 +63,10 @@ Parse the architecture document for statements describing two or more technologi
|
|
|
60
63
|
|
|
61
64
|
<!-- Subagent delegation: read SKILL.md files in parallel, return compact JSON -->
|
|
62
65
|
|
|
63
|
-
For each library in an integration pair, delegate SKILL.md reading to a parallel subagent. Launch up to **8 subagents concurrently** (batch if needed — same 8-way cap as step 1 §2; keeps aggregate token window manageable while still parallelizing typical stack sizes). Each subagent receives one skill's SKILL.md path and
|
|
64
|
-
1.
|
|
65
|
-
2.
|
|
66
|
-
3.
|
|
66
|
+
For each library in an integration pair, delegate SKILL.md reading to a parallel subagent. Launch up to **8 subagents concurrently** (batch if needed — same 8-way cap as step 1 §2; keeps aggregate token window manageable while still parallelizing typical stack sizes). Each subagent receives one skill's SKILL.md path and:
|
|
67
|
+
1. Reads the SKILL.md file
|
|
68
|
+
2. Extracts the API surface
|
|
69
|
+
3. Returns only this compact JSON — no prose, no extra commentary:
|
|
67
70
|
|
|
68
71
|
```json
|
|
69
72
|
{
|
|
@@ -78,13 +81,13 @@ For each library in an integration pair, delegate SKILL.md reading to a parallel
|
|
|
78
81
|
**Extraction rules for subagents:**
|
|
79
82
|
- `skill_name`, `language`: mirror the skill's metadata fields
|
|
80
83
|
- `exports`: exported functions with signatures, exported types/interfaces/classes (extracted from SKILL.md prose)
|
|
81
|
-
- `protocols_inferred`: best-effort prose scan — protocol tokens mentioned in SKILL.md descriptions/examples
|
|
82
|
-
- `data_formats_inferred`: best-effort prose scan — format tokens mentioned in SKILL.md descriptions/examples
|
|
84
|
+
- `protocols_inferred`: best-effort prose scan — protocol tokens mentioned in SKILL.md descriptions/examples; not a declared field in `metadata.json`
|
|
85
|
+
- `data_formats_inferred`: best-effort prose scan — format tokens mentioned in SKILL.md descriptions/examples; not a declared field in `metadata.json`
|
|
83
86
|
- If a field has no matches, return an empty array `[]`
|
|
84
87
|
|
|
85
|
-
**
|
|
88
|
+
**These fields are inferred, not declared.** `protocols` and `data_formats` do not exist in any skill's `metadata.json` — treat them as weak evidence from prose scanning only. When either list is used to justify compatibility in Check 2, cap the per-pair verdict at `Plausible` (see the schema's producer obligations — `{feasibilitySchemaRef}`).
|
|
86
89
|
|
|
87
|
-
**Schema validation (parent):** Each subagent response must contain the required keys (`skill_name`, `language`, `exports`). Reject responses missing required keys and exclude that skill from pair evaluation;
|
|
90
|
+
**Schema validation (parent):** Each subagent response must contain the required keys (`skill_name`, `language`, `exports`). Reject responses missing required keys and exclude that skill from pair evaluation; if more than **20%** (same failure-budget threshold as step 1 §2; see the justification there) of subagent calls return malformed JSON, HALT (exit code 7, `halt_reason: "inventory-unreliable"`) with "API-surface extraction unreliable — more than 20% of subagent reads returned malformed JSON. Re-run [VS] after skills stabilize." In headless, emit the error envelope.
|
|
88
91
|
|
|
89
92
|
**Parent collects all subagent JSON summaries.** Do not load full SKILL.md content into parent context.
|
|
90
93
|
|
|
@@ -98,48 +101,35 @@ For each library in an integration pair, delegate SKILL.md reading to a parallel
|
|
|
98
101
|
|
|
99
102
|
Store collected API surface summaries for cross-referencing.
|
|
100
103
|
|
|
101
|
-
**Integration-evidence source preference:** If the stack was assembled by `skf-create-stack-skill` and a stack manifest (e.g., `integration_patterns` block in the stack skill's `bmad-skill-manifest.yaml` or `metadata.json`) is present in the inventory, use that as the authoritative integration source and cite `source: stack manifest` in each verdict. Fall back to prose co-mention only when no manifest is available, and cite `source: prose co-mention`.
|
|
102
|
-
|
|
103
104
|
### 4. Cross-Reference Each Integration Pair
|
|
104
105
|
|
|
105
|
-
For each integration pair `{library_a, library_b}`,
|
|
106
|
-
|
|
107
|
-
**Check
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
- If no bridge mechanism documented → flag as risk
|
|
111
|
-
|
|
112
|
-
**Check 2 — Protocol Compatibility (best-effort prose scan):**
|
|
113
|
-
- Uses only the `protocols_inferred` / `data_formats_inferred` lists surfaced by the subagent prose scan — these are NOT declared metadata fields
|
|
114
|
-
- Both prose-scanned lists share a protocol token → treat as inferred compatibility (cap verdict at `Plausible`)
|
|
115
|
-
- Complementary tokens (e.g., "HTTP client" in one, "HTTP server" in the other) → inferred compatibility (cap at `Plausible`)
|
|
116
|
-
- Neither skill surfaces any protocol token, or tokens appear to conflict with no adapter mentioned → flag as risk
|
|
117
|
-
- Do NOT assert that protocols come from a declared schema field; when prose evidence is all that's available, the per-pair verdict MUST cap at `Plausible`
|
|
118
|
-
|
|
119
|
-
**Check 3 — Type Compatibility:**
|
|
120
|
-
- Shared types or compatible serialization formats (cited from `exports` signatures) → compatible
|
|
121
|
-
- Incompatible type systems with no conversion layer → flag as risk
|
|
122
|
-
|
|
123
|
-
**Check 4 — Documentation Cross-Reference (REQUIRED for `Verified`):**
|
|
124
|
-
- Search Skill A's SKILL.md for a literal substring/name citation of Skill B's library name (or an explicit alias declared in that skill's metadata)
|
|
125
|
-
- Search Skill B's SKILL.md for the reciprocal citation
|
|
126
|
-
- If a literal citation is found in at least one direction → Check 4 PASSES; record the exact cited substring and its location as evidence
|
|
127
|
-
- If neither skill literally cites the other → Check 4 FAILS (weak/missing evidence); per-pair verdict MUST be capped at `Plausible` regardless of Checks 1–3 outcomes
|
|
128
|
-
|
|
129
|
-
**Assign verdict per pair (per `{feasibilitySchemaRef}`):**
|
|
130
|
-
- **Verified** — Checks 1, 3 pass with declared evidence AND Check 4 passes with a literal substring/name citation recorded in the evidence block. Check 2 is best-effort only; it cannot by itself promote a pair to `Verified`.
|
|
131
|
-
- **Plausible** — Checks pass, but at least one relies on inferred evidence (e.g., Check 2 prose scan) OR Check 4 is weak/missing. This is the cap whenever Check 4 fails.
|
|
132
|
-
- **Risky** — At least one check flags an incompatibility that a workaround may resolve (bridge layer, adapter, serialization shim).
|
|
133
|
-
- **Blocked** — Fundamental incompatibility: language barrier with no bridge documented anywhere in the inventory, or type/protocol mismatch with no adapter mentioned.
|
|
134
|
-
|
|
135
|
-
**Each verdict MUST include:**
|
|
106
|
+
For each integration pair `{library_a, library_b}`, run the four-check protocol and assign the per-pair verdict per `{integrationRulesData}` (loaded in §1): the Cross-Reference Protocol defines Check 1 (language boundary), Check 2 (protocol compatibility), Check 3 (type compatibility), and Check 4 (documentation cross-reference, required for `Verified`); the Verdict Definitions table and promotion rule define the `Verified` / `Plausible` / `Risky` / `Blocked` thresholds and the cap-at-`Plausible` rule that applies whenever Check 4 surfaces no literal citation. Do not restate those mechanics here.
|
|
107
|
+
|
|
108
|
+
**Step-specific input for Check 2:** Check 2 draws only on the `protocols_inferred` / `data_formats_inferred` lists surfaced by the §3 subagent prose scan. A shared or complementary token (e.g., "HTTP client" ↔ "HTTP server") reads as inferred compatibility; no token on either side, or conflicting tokens with no adapter, flags a risk. Any pair whose compatibility rests on this inferred evidence caps at `Plausible` per §3.
|
|
109
|
+
|
|
110
|
+
**Each verdict includes:**
|
|
136
111
|
- Which checks passed and which flagged
|
|
137
112
|
- Evidence citations: specific exports, types, or literal substrings from the skills
|
|
138
|
-
- `source: stack manifest` or `source: prose co-mention` tag (per section
|
|
113
|
+
- `source: stack manifest` or `source: prose co-mention` tag (per section 2)
|
|
139
114
|
- For `Verified`: the exact Check 4 literal citation (e.g., `"see also: {lib_b}"` quoted from Skill A's SKILL.md, line N)
|
|
140
115
|
- **Tier annotation:** For each contributing skill, append `(evidence from Tier {n} skill)` citing that skill's `confidence_tier` (e.g., `(evidence from Tier 1 skill)`). This lets reviewers weigh evidence strength by extraction confidence.
|
|
141
116
|
|
|
142
|
-
**Cycle detection (after all pairs evaluated):**
|
|
117
|
+
**Cycle detection (after all pairs evaluated):** Deciding the edge set is a Check-4 judgment and stays here; the traversal is deterministic and is delegated to the shared helper (the in-prose DFS misses real multi-hop cycles or invents spurious ones as the pair count grows).
|
|
118
|
+
|
|
119
|
+
1. **Build the directed pair graph in the prompt:** an edge `A → B` exists when skill A literally cites skill B via Check 4. Serialize the edges as JSON: `{"edges": [["A", "B"], ["B", "C"], ...]}` (each `[from, to]` pair is one Check-4 citation direction).
|
|
120
|
+
2. **Resolve `{cycleFinderHelper}`** from `{cycleFinderProbeOrder}`; first existing path wins. Enumerate cycles deterministically (run `uv run {cycleFinderHelper} find --help` for the contract):
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
uv run {cycleFinderHelper} find --edges -
|
|
124
|
+
```
|
|
125
|
+
piping the edges JSON on stdin (use a temp file under `{forge_data_folder}/` if stdin piping is unavailable). The script emits:
|
|
126
|
+
```json
|
|
127
|
+
{"cycles": [["A", "B", "C", "A"], ...], "cycle_count": N}
|
|
128
|
+
```
|
|
129
|
+
Each `cycles[]` entry is a closed node path (first node repeated at the end); every simple directed cycle appears exactly once, de-duplicated across rotations.
|
|
130
|
+
|
|
131
|
+
**Graceful degradation:** if no `{cycleFinderProbeOrder}` candidate exists (e.g. `uv` unavailable on claude.ai web), run the equivalent DFS (visited set + recursion stack) directly per the `--help` contract and proceed with the same cycle set.
|
|
132
|
+
3. **For each cycle** in `cycles[]`, append a synthetic row to the verdict table with verdict `Risky` and rationale "circular integration dependency detected: `{A → B → C → A}`" (render the arrow chain from the cycle's node path). Do not otherwise modify the individual pair verdicts.
|
|
143
133
|
|
|
144
134
|
### 5. Display Integration Results
|
|
145
135
|
|
|
@@ -166,18 +156,23 @@ For each integration pair `{library_a, library_b}`, apply the verification proto
|
|
|
166
156
|
|
|
167
157
|
### 6. Append to Report
|
|
168
158
|
|
|
169
|
-
**Resolve `{atomicWriteHelper}`** from `{atomicWriteProbeOrder}`; first existing path wins.
|
|
159
|
+
**Resolve `{atomicWriteHelper}`** from `{atomicWriteProbeOrder}`; first existing path wins. If no candidate exists: HALT (exit code 3, `halt_reason: "resolution-failure"`); in headless, emit the error envelope.
|
|
170
160
|
|
|
171
|
-
Write the **Integration Verdicts** section to `{outputFile}` (heading is fixed — consumers grep for `## Integration Verdicts`; the table header
|
|
172
|
-
- Emit the canonical `| lib_a | lib_b | verdict | rationale |` table first (verdict tokens
|
|
161
|
+
Write the **Integration Verdicts** section to `{outputFile}` (heading is fixed — consumers grep for `## Integration Verdicts`; the table header is the canonical `| lib_a | lib_b | verdict | rationale |` per `{feasibilitySchemaRef}`, and consumers parse that exact header, so a different one breaks them; the skill-local display table with the extra Context/Source/Evidence columns can be rendered beneath it for human readers):
|
|
162
|
+
- Emit the canonical `| lib_a | lib_b | verdict | rationale |` table first (verdict tokens are exactly one of `Verified`, `Plausible`, `Risky`, `Blocked`, case-sensitive — any other token is a schema violation consumers reject)
|
|
173
163
|
- Include the extended table with Context, Source, and Evidence columns below it
|
|
174
|
-
- Include recommendations for Risky and Blocked pairs (Blocked
|
|
164
|
+
- Include recommendations for Risky and Blocked pairs (each Blocked recommendation cites a named candidate per step 5 H6, or the explicit no-candidate notice)
|
|
175
165
|
- Update frontmatter: append `'integrations'` to `stepsCompleted`; set `pairsVerified`, `pairsPlausible`, `pairsRisky`, `pairsBlocked` counts
|
|
176
166
|
- Pipe the updated full content through `python3 {atomicWriteHelper} write --target {outputFile}` and again with `--target {outputFileLatest}`
|
|
177
167
|
|
|
178
168
|
### 7. Auto-Proceed to Next Step
|
|
179
169
|
|
|
180
|
-
**Early halt guard:** If ALL integration pairs are Blocked, present: "**All integrations are Blocked** — fundamental incompatibilities detected across all library pairs. Remaining analysis will produce limited value. **[X] Halt workflow (recommended)** | **[C] Continue anyway**" — wait for user input.
|
|
170
|
+
**Early halt guard:** If ALL integration pairs are Blocked, present: "**All integrations are Blocked** — fundamental incompatibilities detected across all library pairs. Remaining analysis will produce limited value. **[X] Halt workflow (recommended)** | **[C] Continue anyway**" — wait for user input.
|
|
171
|
+
|
|
172
|
+
**GATE [default: C]** — Interactive-only guard. If `{headless_mode}`: auto-proceed with [C] Continue, log: "headless: continuing past all-Blocked integration gate". Headless never takes [X], so step 6 still emits the result contract — any Blocked pair resolves the run to `NOT_FEASIBLE` in synthesize.
|
|
173
|
+
|
|
174
|
+
- If X: halt with: "**Workflow halted — all integrations blocked.** Integration Verdicts saved to `{outputFile}`. Run **[VS]** after applying architectural changes. **Blocked integrations:** {list each blocked pair with reason}." HALT (exit code 8, `halt_reason: "analysis-halted"`).
|
|
175
|
+
- If C: continue.
|
|
181
176
|
|
|
182
177
|
{IF NOT halted (user selected C, or early halt guard did not trigger):}
|
|
183
178
|
|
|
@@ -11,6 +11,9 @@ feasibilitySchemaProbeOrder:
|
|
|
11
11
|
atomicWriteProbeOrder:
|
|
12
12
|
- '{project-root}/_bmad/skf/shared/scripts/skf-atomic-write.py'
|
|
13
13
|
- '{project-root}/src/shared/scripts/skf-atomic-write.py'
|
|
14
|
+
validateFeasibilityReportProbeOrder:
|
|
15
|
+
- '{project-root}/_bmad/skf/shared/scripts/skf-validate-feasibility-report.py'
|
|
16
|
+
- '{project-root}/src/shared/scripts/skf-validate-feasibility-report.py'
|
|
14
17
|
nextStepFile: 'health-check.md'
|
|
15
18
|
---
|
|
16
19
|
|
|
@@ -25,7 +28,7 @@ Present the complete feasibility report to the user. Display the overall verdict
|
|
|
25
28
|
## Rules
|
|
26
29
|
|
|
27
30
|
- Focus only on presenting the completed report — no new analysis or changes to verdicts
|
|
28
|
-
- Chains to the local health-check step via `{nextStepFile}` after completion — the user-facing report is
|
|
31
|
+
- Chains to the local health-check step via `{nextStepFile}` after completion — the user-facing report is not the terminal step
|
|
29
32
|
|
|
30
33
|
## MANDATORY SEQUENCE
|
|
31
34
|
|
|
@@ -35,11 +38,24 @@ Read the entire `{outputFile}` to have all data available for presentation.
|
|
|
35
38
|
|
|
36
39
|
**Resolve `{feasibilitySchemaRef}`** from `{feasibilitySchemaProbeOrder}`; first existing path wins (installed SKF module path first, dev-checkout `src/` fallback).
|
|
37
40
|
|
|
38
|
-
|
|
41
|
+
**Validate report structure and schema version (deterministic gate).** Resolve `{validateFeasibilityReportHelper}` from `{validateFeasibilityReportProbeOrder}`; first existing path wins (installed SKF module path first, dev-checkout `src/` fallback). Then run:
|
|
39
42
|
|
|
40
|
-
|
|
43
|
+
```bash
|
|
44
|
+
python3 {validateFeasibilityReportHelper} {outputFile}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The script (see `--help`) deterministically confirms the five required body sections — `## Executive Summary`, `## Coverage Analysis`, `## Integration Verdicts`, `## Recommendations`, `## Evidence Sources` — are all present and in canonical order per `{feasibilitySchemaRef}`, **and** that frontmatter `schemaVersion == "1.0"`. It emits a JSON verdict on stdout (`headingsOk`, `missingHeadings`, `orderViolations`, `schemaVersionOk`, `schemaVersionFound`, `violation`) and exits `0` when valid, `1` on a schema violation, `2` on an IO/parse error.
|
|
48
|
+
|
|
49
|
+
**Graceful degradation:** if no `{validateFeasibilityReportProbeOrder}` candidate exists (e.g. partial installation, or `python3` unavailable), perform the equivalent structural check inline — confirm the five headings above are all present and in that exact order, and that frontmatter `schemaVersion` is `"1.0"` — and apply the same halt semantics below. The report is already on disk from steps 1-5, so a missing validator degrades to the inline check rather than blocking presentation.
|
|
50
|
+
|
|
51
|
+
On any non-zero exit (or an inline check that fails), HALT (exit code 5, `halt_reason: "schema-violation"`) — do not display partial results. Report the specific violation from the JSON:
|
|
41
52
|
|
|
42
|
-
|
|
53
|
+
- a missing or out-of-order section (`missingHeadings` / `orderViolations`); or
|
|
54
|
+
- a schemaVersion mismatch — "Report frontmatter schemaVersion `{schemaVersionFound}` does not match producer schema `1.0` — report was corrupted between steps. Re-run [VS]." (Producer never proceeds past a schema mismatch.)
|
|
55
|
+
|
|
56
|
+
In headless, emit the error envelope per SKILL.md "Result Contract (Headless)" with `report_path: "{outputFile}"`, `overall_verdict: null`.
|
|
57
|
+
|
|
58
|
+
With the deterministic gate passed (sections present + in order, `schemaVersion == "1.0"`), **extract metrics from `{outputFile}` frontmatter** (per shared schema in `{feasibilitySchemaRef}`): `skillsAnalyzed`, `coveragePercentage`, `pairsVerified` (as `verified_count`), `pairsPlausible` (as `plausible_count`), `pairsRisky` (as `risky_count`), `pairsBlocked` (as `blocked_count`), `requirementsFulfilled` (as `fulfilled_count`), `requirementsPartial` (as `partial_count`), `requirementsNotAddressed` (as `not_addressed_count`), `requirementsPass`, `overallVerdict`, and `recommendationCount`. Use these mapped display names in the summary table and next steps below.
|
|
43
59
|
|
|
44
60
|
### 2. Present Summary
|
|
45
61
|
|
|
@@ -76,37 +92,17 @@ Walk through the highlights — coverage gaps, risky/blocked integrations, and p
|
|
|
76
92
|
|
|
77
93
|
### 4. Present Next Steps
|
|
78
94
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
**IF `overallVerdict == "FEASIBLE"`:**
|
|
82
|
-
"**Your stack is verified.** All technologies are covered, integrations are compatible, and requirements are all fulfilled (or requirements pass was skipped).
|
|
83
|
-
|
|
84
|
-
**Recommended next steps:**
|
|
85
|
-
1. **[RA] Refine Architecture** — Produce an implementation-ready architecture document enriched with skill-backed API details
|
|
86
|
-
2. **[SS] Create Stack Skill** — compose your individual skills into a unified stack skill, providing the refined architecture doc when prompted
|
|
87
|
-
3. **[TS] Test Skill** → **[EX] Export Skill** — Verify completeness and package for distribution"
|
|
88
|
-
|
|
89
|
-
**IF `overallVerdict == "CONDITIONALLY_FEASIBLE"`:**
|
|
90
|
-
"**Your stack is conditionally feasible.** There are {recommendationCount} items to address before proceeding.
|
|
91
|
-
|
|
92
|
-
**Required actions:**
|
|
93
|
-
{List the specific recommendations from Step 05 synthesis}
|
|
94
|
-
|
|
95
|
-
**After addressing these items:** Re-run **[VS] Verify Stack** to confirm resolution, then proceed to **[RA]**."
|
|
96
|
-
|
|
97
|
-
**IF `overallVerdict == "NOT_FEASIBLE"`:**
|
|
98
|
-
"**Critical blockers must be resolved.** The stack cannot support the architecture as described.
|
|
99
|
-
|
|
100
|
-
**Critical actions:**
|
|
101
|
-
{List the blocked integration recommendations and missing skill actions from Step 05}
|
|
95
|
+
Step 05 already wrote a **Suggested next workflow** block (keyed on the case-sensitive `overallVerdict` token) at the end of `## Recommendations`. Surface that block from the §1 load rather than re-deriving it, prefixed with the one-line verdict-specific framing:
|
|
102
96
|
|
|
103
|
-
**
|
|
97
|
+
- **`FEASIBLE`:** "**Your stack is verified.** All technologies are covered, integrations are compatible, and requirements are all fulfilled (or requirements pass was skipped)."
|
|
98
|
+
- **`CONDITIONALLY_FEASIBLE`:** "**Your stack is conditionally feasible.** There are {recommendationCount} items to address before proceeding." — then list the specific recommendations from the report's `## Recommendations` section.
|
|
99
|
+
- **`NOT_FEASIBLE`:** "**Critical blockers must be resolved.** The stack cannot support the architecture as described." — then list the blocked-integration and missing-skill recommendations from the report's `## Recommendations` section.
|
|
104
100
|
|
|
105
101
|
### 4b. Result Contract
|
|
106
102
|
|
|
107
|
-
**Resolve `{atomicWriteHelper}`** from `{atomicWriteProbeOrder}`; first existing path wins.
|
|
103
|
+
**Resolve `{atomicWriteHelper}`** from `{atomicWriteProbeOrder}`; first existing path wins. If no candidate exists: HALT (exit code 3, `halt_reason: "resolution-failure"`); in headless, emit the error envelope.
|
|
108
104
|
|
|
109
|
-
Write the result contract per `shared/references/output-contract-schema.md
|
|
105
|
+
Write the result contract per `shared/references/output-contract-schema.md` (this path resolves relative to the SKF module root — `{project-root}/_bmad/skf/` when installed, `{project-root}/src/` during development — not relative to this step file): the per-run record at `{forge_data_folder}/verify-stack-result-{YYYYMMDD-HHmmss}.json` (UTC timestamp, resolution to seconds) and a copy at `{forge_data_folder}/verify-stack-result-latest.json` (stable path for pipeline consumers — copy, not symlink). Include the feasibility report path (both `{outputFile}` and `{outputFileLatest}`) in `outputs`; include `overallVerdict` (`FEASIBLE` / `CONDITIONALLY_FEASIBLE` / `NOT_FEASIBLE`), `coveragePercentage`, and `recommendationCount` in `summary` — use the case-sensitive schema tokens.
|
|
110
106
|
|
|
111
107
|
Write both JSON files through `python3 {atomicWriteHelper} write --target ...` to avoid partial-write corruption. On any non-zero exit: HALT (exit code 4, `halt_reason: "write-failed"`) and emit the error envelope.
|
|
112
108
|
|
|
@@ -118,7 +114,7 @@ SKF_VERIFY_STACK_RESULT_JSON: {"status":"success","report_path":"{outputFile}","
|
|
|
118
114
|
|
|
119
115
|
`{overallVerdict}` uses the schema tokens (`FEASIBLE` / `CONDITIONALLY_FEASIBLE` / `NOT_FEASIBLE`).
|
|
120
116
|
|
|
121
|
-
**Result-contract ordering:** The result contract is written exactly once on the first entry to step 6 (the `[X] Exit verification` path). Re-walks of the report via the `[R] Review full report` menu option do
|
|
117
|
+
**Result-contract ordering:** The result contract is written exactly once on the first entry to step 6 (the `[X] Exit verification` path). Re-walks of the report via the `[R] Review full report` menu option do not regenerate it — the contract captures the run, not the presentation loop. If the user selects `[R]` repeatedly before exiting, the single on-disk contract written on first entry remains authoritative.
|
|
122
118
|
|
|
123
119
|
### 5. Present Menu
|
|
124
120
|
|
|
@@ -133,13 +129,11 @@ Re-run **[VS] Verify Stack** anytime after making changes to your skills or arch
|
|
|
133
129
|
|
|
134
130
|
**Verification workflow complete.**"
|
|
135
131
|
|
|
136
|
-
Then load, read the full file, and execute `{nextStepFile}` — the health-check step is the true terminal step of this workflow.
|
|
132
|
+
If `{workflow.on_complete}` is non-empty, execute it now (e.g. route the verdict onward or trigger a downstream step); in headless, log the action. Then load, read the full file, and execute `{nextStepFile}` — the health-check step is the true terminal step of this workflow.
|
|
137
133
|
|
|
138
134
|
#### EXECUTION RULES:
|
|
139
135
|
|
|
140
|
-
- ALWAYS halt and wait for user input after presenting the menu
|
|
141
136
|
- **GATE [default: X]** — If `{headless_mode}`: auto-proceed with [X] Exit verification, log: "headless: auto-exit past report menu"
|
|
142
137
|
- R may be selected multiple times — always walk through the full report
|
|
143
|
-
- X triggers the health check, which is the true workflow exit
|
|
144
138
|
|
|
145
139
|
|
|
@@ -28,7 +28,7 @@ If a PRD or vision document was provided in Step 01, verify that the combined ca
|
|
|
28
28
|
|
|
29
29
|
### 1. Check PRD Availability
|
|
30
30
|
|
|
31
|
-
**Resolve `{atomicWriteHelper}`** from `{atomicWriteProbeOrder}`; first existing path wins.
|
|
31
|
+
**Resolve `{atomicWriteHelper}`** from `{atomicWriteProbeOrder}`; first existing path wins. If no candidate exists: HALT (exit code 3, `halt_reason: "resolution-failure"`); in headless, emit the error envelope.
|
|
32
32
|
|
|
33
33
|
**Read `prdAvailable` from `{outputFile}` frontmatter (set in Step 01). If `prdAvailable` is false (no PRD/vision document was provided):**
|
|
34
34
|
|
|
@@ -42,7 +42,7 @@ To include this pass, re-run **[VS]** with a PRD or vision document path.
|
|
|
42
42
|
|
|
43
43
|
Update `{outputFile}` frontmatter: append `'requirements'` to `stepsCompleted`; set `requirementsPass: "skipped"`. Pipe the updated content through `python3 {atomicWriteHelper} write --target {outputFile}` and again with `--target {outputFileLatest}`.
|
|
44
44
|
|
|
45
|
-
Load, read the full file and then execute `{nextStepFile}`.
|
|
45
|
+
Load, read the full file and then execute `{nextStepFile}`. The no-PRD path ends here — sections 2-6 are the PRD-present branch and do not run.
|
|
46
46
|
|
|
47
47
|
**If PRD/vision document was provided:** Continue to section 2.
|
|
48
48
|
|
|
@@ -78,7 +78,7 @@ For each requirement, evaluate whether the combined capabilities of the generate
|
|
|
78
78
|
- **Partially Fulfilled** — skills provide related capability but gaps remain (specify what is covered and what is not)
|
|
79
79
|
- **Not Addressed** — no skill in the stack provides capability relevant to this requirement
|
|
80
80
|
|
|
81
|
-
**Each verdict
|
|
81
|
+
**Each verdict includes:**
|
|
82
82
|
- Which skills contribute (if any)
|
|
83
83
|
- Specific exports or capabilities from those skills that are relevant
|
|
84
84
|
- For Partially Fulfilled: what gap remains
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
nextStepFile: 'report.md'
|
|
3
|
+
verdictRollupScript: 'scripts/skf-verdict-rollup.py'
|
|
4
|
+
reportDeltaScript: 'scripts/skf-report-delta.py'
|
|
3
5
|
feasibilitySchemaProbeOrder:
|
|
4
6
|
- '{project-root}/_bmad/skf/shared/references/feasibility-report-schema.md'
|
|
5
7
|
- '{project-root}/src/shared/references/feasibility-report-schema.md'
|
|
@@ -27,33 +29,29 @@ Calculate the overall feasibility verdict based on all three analysis passes, ge
|
|
|
27
29
|
|
|
28
30
|
### 1. Calculate Overall Verdict
|
|
29
31
|
|
|
30
|
-
**
|
|
32
|
+
**The verdict token is deterministic — do not walk the ladder in prose.** All three passes have already persisted their counts (`coveragePercentage`, `pairsBlocked`/`pairsRisky`/`pairsPlausible`/`pairsVerified`, `requirementsPass` + `requirementsNotAddressed`/`requirementsPartial` in `{outputFile}` frontmatter; the Missing technology count in the Coverage Analysis table). Rolling those already-decided counts up into one token has a single correct answer per input, so delegate it. Count Missing rows directly from the Coverage table — half-up rounding can leave `coveragePercentage == 100` with one technology still Missing — assemble the counts, and run:
|
|
31
33
|
|
|
32
|
-
|
|
34
|
+
```bash
|
|
35
|
+
echo '<counts JSON>' | uv run {verdictRollupScript} --stdin
|
|
36
|
+
```
|
|
33
37
|
|
|
34
|
-
|
|
38
|
+
Input keys: `coveragePercentage`, `missingCount`, `pairsBlocked`, `pairsRisky`, `pairsPlausible`, `pairsVerified`; plus, only when the requirements pass ran (`requirementsPass == "completed"`), `requirementsEvaluated: true` with `requirementsNotAddressed`/`requirementsPartial`; plus `continuedPastZeroState: true` if the user pressed `[C] Continue anyway` past a step-2 zero-state gate (all-Replaced or 0%-coverage). The script (run `uv run {verdictRollupScript} --help` for the contract) returns `overallVerdict` (one of `FEASIBLE`/`CONDITIONALLY_FEASIBLE`/`NOT_FEASIBLE`), `matchedConditions` (the condition codes that fired), and `zeroPairsGuardFired`. If `uv` is unavailable (e.g. claude.ai web), apply the ladder below inline.
|
|
35
39
|
|
|
36
|
-
**
|
|
37
|
-
-
|
|
38
|
-
-
|
|
40
|
+
**The ladder it applies (documented so the rationale can cite it — the script is the executor; evaluate top-to-bottom, first match wins):**
|
|
41
|
+
- `coveragePercentage == 0` → `NOT_FEASIBLE` (short-circuit: no live coverage, analysis vacuous).
|
|
42
|
+
- Any Blocked integration → `NOT_FEASIBLE` (fundamental architectural incompatibility).
|
|
43
|
+
- Any Missing technology, any Risky integration, or — when requirements ran — any Not Addressed / Partially Fulfilled requirement → `CONDITIONALLY_FEASIBLE`.
|
|
44
|
+
- Otherwise → `FEASIBLE`, but any pair capped at `Plausible` (including Check-4-missing caps) downgrades to `CONDITIONALLY_FEASIBLE`.
|
|
45
|
+
- Post-verdict guard: when all four integration counts are 0 and the user continued past a step-2 zero-state gate, `zeroPairsGuardFired` is true — a `FEASIBLE` verdict is overridden to `CONDITIONALLY_FEASIBLE`.
|
|
39
46
|
|
|
40
|
-
**CONDITIONALLY_FEASIBLE
|
|
41
|
-
If ANY of the following apply, the verdict is `CONDITIONALLY_FEASIBLE`. Include ALL matching conditions in the rationale:
|
|
42
|
-
- Any technology is **Missing** from coverage (no skill exists). Technologies marked **Replaced** in Step 02 are intentionally being removed and do NOT count as Missing — they never trigger CONDITIONALLY_FEASIBLE or a [CS]/[QS] recommendation.
|
|
43
|
-
- Any integration is **Risky** (but none Blocked)
|
|
44
|
-
- Requirements have any **Not Addressed** items
|
|
45
|
-
- Requirements have any **Partially Fulfilled** items
|
|
46
|
-
- Rationale: the stack can work but has gaps, risks, or unverified assumptions that must be addressed
|
|
47
|
+
Technologies marked **Replaced** in Step 02 are intentionally being removed and are already excluded from `missingCount` and the coverage denominator — they never trigger `CONDITIONALLY_FEASIBLE` or a [CS]/[QS] recommendation.
|
|
47
48
|
|
|
48
|
-
**
|
|
49
|
-
-
|
|
50
|
-
-
|
|
51
|
-
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
If zero integration pairs were extracted (all four integration counts are 0), fire the guard whenever the user continued past the step 2 `[C] Continue anyway` prompt (i.e., any `[C]` continuation from 0% coverage or any other zero-state) — regardless of how many technologies the architecture document references:
|
|
55
|
-
- If the verdict was `FEASIBLE`, override to `CONDITIONALLY_FEASIBLE`
|
|
56
|
-
- Regardless of verdict, append this note to the rationale: "No integration claims were found in the architecture document prose. Manual review recommended to confirm that technology relationships are not documented exclusively in diagrams or implied without explicit co-mention."
|
|
49
|
+
**Write the rationale** from `matchedConditions`, naming the specific findings behind each code:
|
|
50
|
+
- `zero-coverage` → "no coverage — analysis vacuous: zero generated skills match the architecture's referenced technologies, so integration and requirements verdicts cannot produce meaningful evidence." Then proceed directly to section 2 to generate recommendations for the Missing and/or Replaced technologies surfaced by Step 02.
|
|
51
|
+
- `blocked-integration` → a blocked integration is a fundamental architectural incompatibility; name each Blocked pair and note any co-occurring `missing-coverage`/`risky-integration` codes so the user sees the full set of problems.
|
|
52
|
+
- `missing-coverage` / `risky-integration` / `requirements-not-addressed` / `requirements-partial` / `plausible-cap` → the stack can work but has gaps, risks, or unverified assumptions that must be addressed; name the specific items behind each code.
|
|
53
|
+
- No codes (`FEASIBLE`) → {IF requirements pass completed:} the stack can support the architecture as described — all requirements fully fulfilled, every integration pair has a literal cross-reference. {IF requirements pass was skipped:} the stack can support the architecture as described — requirements were not evaluated (no PRD provided).
|
|
54
|
+
- `zero-integration-pairs` (present whenever the guard fired, regardless of verdict) → append: "No integration claims were found in the architecture document prose. Manual review recommended to confirm that technology relationships are not documented exclusively in diagrams or implied without explicit co-mention."
|
|
57
55
|
|
|
58
56
|
Store the verdict for use in the report.
|
|
59
57
|
|
|
@@ -66,7 +64,7 @@ For each non-verified finding across all passes, generate an actionable next ste
|
|
|
66
64
|
|
|
67
65
|
**Replaced / being-removed technology (from Step 02):**
|
|
68
66
|
- "`{library_name}` is marked for removal/replacement in the architecture document — no skill is needed. Remove it from the architecture document (or, if it is in fact staying, correct the document to drop the removal marker), then re-run **[VS]**."
|
|
69
|
-
- Do
|
|
67
|
+
- Do not emit a [CS]/[QS] recommendation for a Replaced technology — forging a skill for a technology that is being deleted is exactly the misfire this category prevents.
|
|
70
68
|
|
|
71
69
|
**Risky integration (from Step 03):**
|
|
72
70
|
- If protocol mismatch → "Consider adding a bridge layer between `{lib_a}` and `{lib_b}` (e.g., HTTP adapter, message queue). Document the bridge in the architecture."
|
|
@@ -89,18 +87,20 @@ For each non-verified finding across all passes, generate an actionable next ste
|
|
|
89
87
|
|
|
90
88
|
### 3. Check for Previous Report
|
|
91
89
|
|
|
92
|
-
Read `previousReport` from `{outputFile}` frontmatter (set in Step 01).
|
|
90
|
+
Read `previousReport` from `{outputFile}` frontmatter (set in Step 01). Each run writes a new timestamped `feasibility-report-{projectSlug}-{timestamp}.md`, so prior reports persist on disk automatically — Step 01 auto-discovers the most recent one for delta comparison when no path is supplied. `previousReport` holds the resolved path, or is empty when no prior report exists or the user skipped the comparison.
|
|
93
91
|
|
|
94
|
-
**Note:**
|
|
92
|
+
**Note:** A manual backup is only needed to compare against a *specific older* snapshot rather than the most recent prior run; provide that backup path when prompted in Step 01.
|
|
95
93
|
|
|
96
94
|
**If a previous report is found:**
|
|
97
|
-
-
|
|
98
|
-
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
95
|
+
- Extract from both reports (current run + the previous report's tables/inventory block): the coverage findings (`{technology, verdict}`), the integration findings (`{libA, libB, verdict}`), and each skill's `confidence_tier`. Reading the tables is judgment; classifying the difference is not — so hand the two extracted finding sets to the delta helper rather than diffing in prose (matching pair keys and applying the verdict ranking by hand drifts between runs).
|
|
96
|
+
- Serialize as `{"previous": {"coverage": […], "integration": […]}, "current": {…}, "previousTiers": {skill: tier}, "currentTiers": {…}}` and run:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
echo '<delta JSON>' | uv run {reportDeltaScript} --stdin
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
The script (run `uv run {reportDeltaScript} --help` for the contract and rankings) returns `improved`/`regressed`/`unchanged`/`new`/`dropped`/`replaced` label lists with counts, plus `tierDowngrades` (each `{skill, from, to}`) — a tier drop (Tier 1 → Tier 2, or T1 → T1-low) counts as a regression. If `uv` is unavailable, apply the ranking from `--help` inline (coverage Missing<Covered; integration Blocked<Risky<Plausible<Verified; tier T2<T1-low<T1; Replaced findings bucketed, not scored).
|
|
103
|
+
- Render the delta section from those results. For each tier downgrade, flag: "skill `{skill}` regressed from `{from}` to `{to}` — re-extract with [CS] at the prior tier level".
|
|
104
104
|
|
|
105
105
|
**If no previous report found:**
|
|
106
106
|
- Note: "First verification run — no delta available."
|
|
@@ -129,7 +129,7 @@ Assemble the following for the report:
|
|
|
129
129
|
|
|
130
130
|
### 5. Append to Report
|
|
131
131
|
|
|
132
|
-
**Resolve `{atomicWriteHelper}`** from `{atomicWriteProbeOrder}`; first existing path wins.
|
|
132
|
+
**Resolve `{atomicWriteHelper}`** from `{atomicWriteProbeOrder}`; first existing path wins. If no candidate exists: HALT (exit code 3, `halt_reason: "resolution-failure"`); in headless, emit the error envelope.
|
|
133
133
|
|
|
134
134
|
**Resolve `{feasibilitySchemaRef}`** from `{feasibilitySchemaProbeOrder}`; first existing path wins (installed SKF module path first, dev-checkout `src/` fallback).
|
|
135
135
|
|
|
@@ -141,14 +141,11 @@ Write the **Recommendations** and **Evidence Sources** sections to `{outputFile}
|
|
|
141
141
|
- Populate `## Evidence Sources` with per-skill citations (SKILL.md path, `metadata_schema_version`, `confidence_tier`, stack manifest if any) and architecture/PRD doc paths
|
|
142
142
|
- Update frontmatter (shared-schema keys):
|
|
143
143
|
- Append `'synthesize'` to `stepsCompleted`
|
|
144
|
-
- Set `overallVerdict` to one of `FEASIBLE`, `CONDITIONALLY_FEASIBLE`, `NOT_FEASIBLE` (case-sensitive, underscores
|
|
144
|
+
- Set `overallVerdict` to one of `FEASIBLE`, `CONDITIONALLY_FEASIBLE`, `NOT_FEASIBLE` (case-sensitive, underscores not spaces)
|
|
145
145
|
- Set `recommendationCount` to the total number of recommendations
|
|
146
|
-
- If delta was computed (section 3), set `deltaImproved`, `deltaRegressed`, `deltaNew`, `deltaUnchanged`
|
|
146
|
+
- If delta was computed (section 3), set `deltaImproved`, `deltaRegressed`, `deltaNew`, `deltaUnchanged` from the delta helper's `improvedCount` / `regressedCount` / `newCount` / `unchangedCount`
|
|
147
147
|
- Verify that `pairsVerified`, `pairsPlausible`, `pairsRisky`, `pairsBlocked` match the counts from Step 03 (these were set in Step 03). If a discrepancy is found, overwrite the frontmatter counts with the values from Step 03 — the report file is the system of record
|
|
148
|
-
- **Overall verdict enforcement (schema producer obligation):**
|
|
149
|
-
- If any pair has Check 4 missing/weak AND was capped at `Plausible`, that alone does NOT force `NOT_FEASIBLE`, but `FEASIBLE` requires zero such pairs
|
|
150
|
-
- `FEASIBLE` requires 100% coverage AND zero Blocked pairs AND zero Check-4-missing pairs — otherwise downgrade to `CONDITIONALLY_FEASIBLE`
|
|
151
|
-
- `coveragePercentage == 0` forces `NOT_FEASIBLE` (per section 1 short-circuit)
|
|
148
|
+
- **Overall verdict enforcement (schema producer obligation):** write the `overallVerdict` the §1 rollup script returned verbatim — do not re-derive the ladder here. §1 (via `{verdictRollupScript}`) is its single source of truth (the 100%-coverage + zero-Blocked + zero-Check-4-missing bar for `FEASIBLE`, and the `coveragePercentage == 0` → `NOT_FEASIBLE` short-circuit included).
|
|
152
149
|
- Pipe the updated full content through `python3 {atomicWriteHelper} write --target {outputFile}` and again with `--target {outputFileLatest}`
|
|
153
150
|
|
|
154
151
|
### 6. Auto-Proceed to Next Step
|