bmad-module-skill-forge 2.2.0 → 3.0.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 +49 -49
- package/docs/404.md +10 -8
- package/docs/_data/pinned.yaml +22 -13
- package/docs/_internal/STABILITY.md +58 -35
- package/docs/agents.md +39 -53
- package/docs/architecture.md +65 -51
- package/docs/bmad-synergy.md +53 -51
- package/docs/campaign.md +127 -75
- package/docs/concepts.md +34 -28
- package/docs/examples.md +70 -68
- package/docs/forge-auto.md +34 -31
- package/docs/getting-started.md +118 -57
- package/docs/how-it-works.md +25 -21
- package/docs/index.md +15 -15
- package/docs/skill-model.md +70 -59
- package/docs/troubleshooting.md +135 -18
- package/docs/verifying-a-skill.md +83 -57
- package/docs/why-skf.md +24 -22
- package/docs/workflows.md +274 -110
- package/package.json +18 -10
- package/src/forger/preferences.yaml +8 -1
- package/src/knowledge/agentskills-spec.md +2 -0
- package/src/knowledge/ccc-bridge.md +40 -24
- package/src/knowledge/confidence-tiers.md +9 -5
- package/src/knowledge/overview.md +3 -3
- package/src/knowledge/progressive-capability.md +8 -8
- package/src/knowledge/provenance-tracking.md +9 -5
- package/src/knowledge/qmd-registry.md +2 -2
- package/src/knowledge/skf-knowledge-index.csv +2 -2
- package/src/knowledge/skill-lifecycle.md +18 -11
- package/src/knowledge/split-body-strategy.md +0 -3
- package/src/knowledge/tool-resolution.md +4 -2
- package/src/knowledge/version-paths.md +101 -15
- package/src/module-help.csv +3 -3
- package/src/module.yaml +10 -0
- package/src/shared/data/ast-grep-recipes.yaml +608 -0
- package/src/shared/data/ide-context-files.json +30 -0
- package/src/shared/health-check.md +32 -12
- package/src/shared/references/description-guard-protocol.md +12 -9
- package/src/shared/references/feasibility-report-schema.md +19 -13
- package/src/shared/references/headless-gate-convention.md +55 -3
- package/src/shared/references/output-contract-schema.md +19 -8
- package/src/shared/references/pipeline-contracts.md +94 -29
- package/src/shared/references/tessl-review.md +77 -0
- package/src/shared/scripts/schemas/skf-analyze-result-envelope.v1.json +194 -0
- package/src/shared/scripts/schemas/skf-audit-result-envelope.v1.json +192 -0
- package/src/shared/scripts/schemas/skf-brief-result-envelope.v1.json +32 -4
- package/src/shared/scripts/schemas/skf-campaign-result-envelope.v1.json +174 -0
- package/src/shared/scripts/schemas/skf-create-skill-result-envelope.v1.json +284 -0
- package/src/shared/scripts/schemas/skf-drop-skill-result-envelope.v1.json +164 -0
- package/src/shared/scripts/schemas/skf-export-result-envelope.v1.json +160 -0
- package/src/shared/scripts/schemas/skf-quick-skill-result-envelope.v1.json +261 -0
- package/src/shared/scripts/schemas/skf-refine-architecture-result-envelope.v1.json +192 -0
- package/src/shared/scripts/schemas/skf-rename-skill-result-envelope.v1.json +179 -0
- package/src/shared/scripts/schemas/skf-setup-result-envelope.v1.json +27 -11
- package/src/shared/scripts/schemas/skf-stack-result-envelope.v1.json +176 -0
- package/src/shared/scripts/schemas/skf-test-result-envelope.v1.json +173 -0
- package/src/shared/scripts/schemas/skf-update-result-envelope.v1.json +19 -5
- package/src/shared/scripts/schemas/skf-verify-stack-result-envelope.v1.json +180 -0
- package/src/shared/scripts/schemas/skill-brief.v1.json +34 -0
- package/src/shared/scripts/schemas/workspace-detection.v1.json +1 -1
- package/src/shared/scripts/skf-atomic-write.py +30 -14
- package/src/shared/scripts/skf-build-change-manifest.py +2203 -24
- package/src/shared/scripts/skf-ccc-git-hygiene.py +532 -0
- package/src/shared/scripts/skf-check-unit-records.py +184 -0
- package/src/shared/scripts/skf-check-workspace-drift.py +538 -9
- package/src/shared/scripts/skf-classify-changed-files.py +694 -0
- package/src/shared/scripts/skf-comention-pairs.py +1333 -123
- package/src/shared/scripts/skf-compare-file-hashes.py +1 -1
- package/src/shared/scripts/skf-count-imports.py +1867 -0
- package/src/shared/scripts/skf-count-tokens.py +1 -1
- package/src/shared/scripts/skf-derive-assembly-shape.py +3 -2
- package/src/shared/scripts/skf-description-guard.py +99 -11
- package/src/shared/scripts/skf-detect-docs.py +694 -2
- package/src/shared/scripts/skf-detect-language.py +486 -107
- package/src/shared/scripts/skf-detect-registry.py +887 -0
- package/src/shared/scripts/skf-detect-scripts-assets.py +1 -1
- package/src/shared/scripts/skf-detect-tools.py +209 -27
- package/src/shared/scripts/skf-detect-workspaces.py +506 -30
- package/src/shared/scripts/skf-disqualify-candidates.py +821 -182
- package/src/shared/scripts/skf-emit-brief-result-envelope.py +69 -191
- package/src/shared/scripts/skf-emit-result-envelope.py +1604 -106
- package/src/shared/scripts/skf-enumerate-stack-skills.py +986 -117
- package/src/shared/scripts/skf-extract-public-api.py +4084 -85
- package/src/shared/scripts/skf-extraction-inventory.py +746 -0
- package/src/shared/scripts/skf-extraction-snapshot.py +539 -0
- package/src/shared/scripts/skf-fetch-temporal.py +674 -0
- package/src/shared/scripts/skf-find-cycles.py +97 -29
- package/src/shared/scripts/skf-find-test-report.py +476 -0
- package/src/shared/scripts/skf-forge-tier-rw.py +444 -203
- package/src/shared/scripts/skf-github-fetch.py +365 -0
- package/src/shared/scripts/skf-github-probe.py +661 -0
- package/src/shared/scripts/skf-hash-content.py +166 -12
- package/src/shared/scripts/skf-language-corpora.py +1 -1
- package/src/shared/scripts/skf-load-provenance.py +159 -27
- package/src/shared/scripts/skf-manifest-ops.py +1 -1
- package/src/shared/scripts/skf-merge-ccc-exclusions.py +2307 -223
- package/src/shared/scripts/skf-merge-doc-urls.py +1 -1
- package/src/shared/scripts/skf-names-present.py +221 -0
- package/src/shared/scripts/skf-pair-intersect.py +119 -28
- package/src/shared/scripts/skf-parse-gaps.py +1384 -0
- package/src/shared/scripts/skf-preapply.py +1 -1
- package/src/shared/scripts/skf-preflight.py +161 -27
- package/src/shared/scripts/skf-promote-staged.py +430 -0
- package/src/shared/scripts/skf-provenance-gap-dispatch.py +39 -7
- package/src/shared/scripts/skf-qmd-classify-collections.py +229 -45
- package/src/shared/scripts/skf-quick-batch.py +774 -0
- package/src/shared/scripts/skf-rebuild-managed-sections.py +972 -88
- package/src/shared/scripts/skf-recommend-scope-type.py +323 -156
- package/src/shared/scripts/skf-render-metadata-stats.py +156 -12
- package/src/shared/scripts/skf-render-quick-metadata.py +132 -28
- package/src/shared/scripts/skf-render-stack-metadata.py +976 -0
- package/src/shared/scripts/skf-resolve-authoritative-files.py +128 -13
- package/src/shared/scripts/skf-resolve-package.py +523 -106
- package/src/shared/scripts/skf-rewrite-skill-name.py +433 -47
- package/src/shared/scripts/skf-run-lock.py +577 -0
- package/src/shared/scripts/skf-scan-manifests.py +998 -57
- package/src/shared/scripts/skf-scan-skill-md-structure.py +1341 -37
- package/src/shared/scripts/skf-severity-classify.py +712 -108
- package/src/shared/scripts/skf-shape-detect.py +298 -204
- package/src/shared/scripts/skf-shard-body.py +9 -8
- package/src/shared/scripts/skf-skill-inventory.py +2412 -89
- package/src/shared/scripts/skf-skills-module.py +472 -0
- package/src/shared/scripts/skf-source-tree.py +1796 -0
- package/src/shared/scripts/skf-structural-diff.py +670 -119
- package/src/shared/scripts/skf-tessl-review.py +706 -0
- package/src/shared/scripts/skf-update-active-symlink.py +5 -5
- package/src/shared/scripts/skf-update-run-state.py +624 -0
- package/src/shared/scripts/skf-validate-brief-inputs.py +92 -29
- package/src/shared/scripts/skf-validate-brief-schema.py +4 -1
- package/src/shared/scripts/skf-validate-feasibility-report.py +577 -66
- package/src/shared/scripts/skf-validate-frontmatter.py +103 -26
- package/src/shared/scripts/skf-validate-output.py +712 -64
- package/src/shared/scripts/skf-validate-pins.py +1 -1
- package/src/shared/scripts/skf-verify-no-trace.py +116 -10
- package/src/shared/scripts/skf-verify-provenance-completeness.py +2919 -54
- package/src/shared/scripts/skf-write-skill-brief.py +367 -19
- package/src/shared/tool-requirements.yaml +201 -0
- package/src/skf-analyze-source/SKILL.md +41 -36
- package/src/skf-analyze-source/assets/skill-brief-schema.md +7 -8
- package/src/skf-analyze-source/customize.toml +36 -24
- package/src/skf-analyze-source/references/auto-docs-only.md +58 -20
- package/src/skf-analyze-source/references/continue.md +2 -13
- package/src/skf-analyze-source/references/discover-additional-source.md +147 -0
- package/src/skf-analyze-source/references/generate-briefs.md +121 -55
- package/src/skf-analyze-source/references/headless-contract.md +42 -15
- package/src/skf-analyze-source/references/identify-units.md +96 -110
- package/src/skf-analyze-source/references/init.md +73 -71
- package/src/skf-analyze-source/references/map-and-detect.md +123 -105
- package/src/skf-analyze-source/references/map-unit-exports.md +68 -0
- package/src/skf-analyze-source/references/recommend.md +51 -70
- package/src/skf-analyze-source/references/scan-project.md +60 -84
- package/src/skf-analyze-source/references/scan-root.md +39 -0
- package/src/skf-analyze-source/references/step-auto-scope-coexistence.md +47 -0
- package/src/skf-analyze-source/references/step-auto-scope-corpora.md +53 -0
- package/src/skf-analyze-source/references/step-auto-scope-split.md +91 -0
- package/src/skf-analyze-source/references/step-auto-scope.md +208 -293
- package/src/skf-analyze-source/references/step-shape-detect.md +14 -12
- package/src/skf-analyze-source/references/unit-detection-heuristics.md +37 -42
- package/src/skf-audit-skill/SKILL.md +43 -51
- package/src/skf-audit-skill/assets/drift-report-template.md +27 -3
- package/src/skf-audit-skill/customize.toml +41 -20
- package/src/skf-audit-skill/references/constituent-freshness.md +91 -0
- package/src/skf-audit-skill/references/doc-drift.md +141 -0
- package/src/skf-audit-skill/references/headless-contract.md +29 -0
- package/src/skf-audit-skill/references/init.md +148 -210
- package/src/skf-audit-skill/references/re-index.md +96 -108
- package/src/skf-audit-skill/references/report.md +96 -33
- package/src/skf-audit-skill/references/semantic-diff.md +27 -18
- package/src/skf-audit-skill/references/severity-classify.md +79 -65
- package/src/skf-audit-skill/references/severity-rules.md +15 -6
- package/src/skf-audit-skill/references/structural-diff.md +75 -90
- package/src/skf-audit-skill/references/upstream-checkout.md +77 -0
- package/src/skf-audit-skill/scripts/render-drift-tables.py +685 -0
- package/src/skf-brief-skill/SKILL.md +36 -25
- package/src/skf-brief-skill/assets/description-voice-examples.md +1 -1
- package/src/skf-brief-skill/assets/scope-templates.md +17 -24
- package/src/skf-brief-skill/assets/skill-brief-schema.md +29 -15
- package/src/skf-brief-skill/customize.toml +48 -20
- package/src/skf-brief-skill/references/analyze-target.md +142 -125
- package/src/skf-brief-skill/references/confirm-brief.md +10 -8
- package/src/skf-brief-skill/references/draft-checkpoint.md +36 -17
- package/src/skf-brief-skill/references/gather-intent-ratify.md +68 -0
- package/src/skf-brief-skill/references/gather-intent.md +87 -182
- package/src/skf-brief-skill/references/headless-args.md +84 -16
- package/src/skf-brief-skill/references/health-check.md +1 -1
- package/src/skf-brief-skill/references/invocation-contract.md +18 -13
- package/src/skf-brief-skill/references/portfolio-similarity-check.md +1 -1
- package/src/skf-brief-skill/references/qmd-collection-registration.md +7 -10
- package/src/skf-brief-skill/references/scope-definition.md +123 -47
- package/src/skf-brief-skill/references/step-auto-brief.md +24 -80
- package/src/skf-brief-skill/references/step-auto-validate.md +20 -121
- package/src/skf-brief-skill/references/version-resolution.md +3 -2
- package/src/skf-brief-skill/references/write-brief.md +66 -57
- package/src/skf-campaign/SKILL.md +31 -34
- package/src/skf-campaign/assets/campaign-state-schema.json +25 -4
- package/src/skf-campaign/customize.toml +47 -16
- package/src/skf-campaign/references/campaign-contracts.md +39 -29
- package/src/skf-campaign/references/campaign-directive-spec.md +4 -2
- package/src/skf-campaign/references/health-check.md +7 -16
- package/src/skf-campaign/references/step-01-setup.md +46 -84
- package/src/skf-campaign/references/step-02-strategy.md +31 -30
- package/src/skf-campaign/references/step-03-pins.md +26 -18
- package/src/skf-campaign/references/step-04-provenance.md +24 -23
- package/src/skf-campaign/references/step-05-skill-loop.md +67 -48
- package/src/skf-campaign/references/step-06-batch.md +41 -34
- package/src/skf-campaign/references/step-07-capstone.md +40 -25
- package/src/skf-campaign/references/step-08-verify.md +28 -29
- package/src/skf-campaign/references/step-09-refine.md +29 -30
- package/src/skf-campaign/references/step-10-export.md +48 -36
- package/src/skf-campaign/references/step-11-maintenance.md +31 -34
- package/src/skf-campaign/references/step-resume.md +37 -68
- package/src/skf-campaign/scripts/campaign-deps.py +57 -18
- package/src/skf-campaign/scripts/campaign-parse-manifest.py +361 -54
- package/src/skf-campaign/scripts/campaign-provenance.py +96 -53
- package/src/skf-campaign/scripts/campaign-quality-gate.py +592 -0
- package/src/skf-campaign/scripts/campaign-render-batch.py +257 -49
- package/src/skf-campaign/scripts/campaign-render-kickoff.py +343 -50
- package/src/skf-campaign/scripts/campaign-report.py +204 -37
- package/src/skf-campaign/scripts/campaign-state.py +1128 -0
- package/src/skf-campaign/scripts/campaign-status.py +10 -74
- package/src/skf-campaign/scripts/campaign-validate-pins.py +30 -3
- package/src/skf-campaign/scripts/campaign-validate-state.py +34 -4
- package/src/skf-campaign/templates/campaign-brief-template.yaml +4 -5
- package/src/skf-campaign/templates/campaign-report-template.md +5 -1
- package/src/skf-campaign/templates/kickoff-template.md +0 -14
- package/src/skf-create-skill/SKILL.md +27 -20
- package/src/skf-create-skill/assets/compile-assembly-rules.md +6 -5
- package/src/skf-create-skill/assets/skill-sections.md +15 -5
- package/src/skf-create-skill/customize.toml +20 -8
- package/src/skf-create-skill/references/authoritative-files-protocol.md +41 -42
- package/src/skf-create-skill/references/batch-mode.md +81 -0
- package/src/skf-create-skill/references/ccc-index-check.md +27 -0
- package/src/skf-create-skill/references/compile.md +107 -29
- package/src/skf-create-skill/references/component-extraction.md +113 -91
- package/src/skf-create-skill/references/enrich.md +41 -23
- package/src/skf-create-skill/references/entry-points-by-hand.md +20 -0
- package/src/skf-create-skill/references/extract.md +200 -161
- package/src/skf-create-skill/references/extraction-patterns-by-hand.md +141 -0
- package/src/skf-create-skill/references/extraction-patterns-tracing.md +2 -2
- package/src/skf-create-skill/references/extraction-patterns.md +584 -196
- package/src/skf-create-skill/references/generate-artifacts.md +145 -93
- package/src/skf-create-skill/references/health-check.md +1 -1
- package/src/skf-create-skill/references/load-brief.md +53 -36
- package/src/skf-create-skill/references/relabel-rule.md +12 -0
- package/src/skf-create-skill/references/report.md +28 -59
- package/src/skf-create-skill/references/source-resolution-protocols.md +49 -155
- package/src/skf-create-skill/references/step-auto-shard.md +20 -93
- package/src/skf-create-skill/references/step-doc-rot.md +44 -60
- package/src/skf-create-skill/references/step-doc-sources.md +28 -19
- package/src/skf-create-skill/references/sub/ccc-discover.md +18 -7
- package/src/skf-create-skill/references/sub/fetch-docs.md +106 -59
- package/src/skf-create-skill/references/sub/fetch-temporal.md +53 -166
- package/src/skf-create-skill/references/tier-degradation-rules.md +18 -9
- package/src/skf-create-skill/references/validate.md +173 -99
- package/src/skf-create-skill/scripts/scan-doc-rot.py +232 -99
- package/src/skf-create-stack-skill/SKILL.md +29 -56
- package/src/skf-create-stack-skill/assets/metadata-contract.md +51 -0
- package/src/skf-create-stack-skill/assets/provenance-map-schema.md +15 -15
- package/src/skf-create-stack-skill/assets/stack-skill-template.md +23 -57
- package/src/skf-create-stack-skill/customize.toml +23 -12
- package/src/skf-create-stack-skill/references/compile-stack.md +57 -66
- package/src/skf-create-stack-skill/references/compose-mode-rules.md +24 -44
- package/src/skf-create-stack-skill/references/detect-integrations.md +92 -95
- package/src/skf-create-stack-skill/references/detect-manifests.md +46 -71
- package/src/skf-create-stack-skill/references/generate-output.md +138 -128
- package/src/skf-create-stack-skill/references/init.md +90 -32
- package/src/skf-create-stack-skill/references/integration-patterns.md +1 -17
- package/src/skf-create-stack-skill/references/invocation-contract.md +34 -0
- package/src/skf-create-stack-skill/references/manifest-patterns.md +32 -20
- package/src/skf-create-stack-skill/references/parallel-extract.md +112 -38
- package/src/skf-create-stack-skill/references/rank-and-confirm.md +57 -75
- package/src/skf-create-stack-skill/references/report.md +39 -33
- package/src/skf-create-stack-skill/references/validate.md +20 -39
- package/src/skf-drop-skill/SKILL.md +28 -51
- package/src/skf-drop-skill/customize.toml +44 -30
- package/src/skf-drop-skill/references/execute.md +79 -146
- package/src/skf-drop-skill/references/invocation-contract.md +64 -0
- package/src/skf-drop-skill/references/report.md +46 -30
- package/src/skf-drop-skill/references/select.md +118 -124
- package/src/skf-drop-skill/scripts/dir-sizes.py +54 -26
- package/src/skf-drop-skill/scripts/drop-roster.py +322 -0
- package/src/skf-export-skill/SKILL.md +40 -62
- package/src/skf-export-skill/assets/managed-section-format.md +14 -50
- package/src/skf-export-skill/assets/snippet-format.md +3 -1
- package/src/skf-export-skill/customize.toml +42 -13
- package/src/skf-export-skill/references/generate-snippet.md +54 -46
- package/src/skf-export-skill/references/health-check.md +2 -0
- package/src/skf-export-skill/references/invocation-contract.md +15 -0
- package/src/skf-export-skill/references/load-skill.md +88 -62
- package/src/skf-export-skill/references/manifest-rebuild.md +9 -10
- package/src/skf-export-skill/references/multi-skill-mode.md +4 -4
- package/src/skf-export-skill/references/orphan-context-detection.md +13 -5
- package/src/skf-export-skill/references/orphan-row-detection.md +31 -22
- package/src/skf-export-skill/references/package.md +15 -73
- package/src/skf-export-skill/references/preflight-snippet-root-probe.md +51 -70
- package/src/skf-export-skill/references/result-envelope.md +31 -16
- package/src/skf-export-skill/references/summary.md +41 -17
- package/src/skf-export-skill/references/token-report.md +4 -12
- package/src/skf-export-skill/references/update-context.md +118 -237
- package/src/skf-forger/SKILL.md +61 -37
- package/src/skf-forger/bmad-skill-manifest.yaml +4 -1
- package/src/skf-forger/customize.toml +43 -0
- package/src/skf-forger/references/pipeline-mode.md +73 -18
- package/src/skf-forger/scripts/forge-status.py +299 -0
- package/src/skf-forger/scripts/parse-pipeline.py +322 -54
- package/src/skf-forger/scripts/pipeline-gate.py +428 -0
- package/src/skf-forger/scripts/pipeline-journal.py +1052 -0
- package/src/skf-quick-skill/SKILL.md +54 -53
- package/src/skf-quick-skill/assets/skill-template.md +4 -2
- package/src/skf-quick-skill/customize.toml +51 -20
- package/src/skf-quick-skill/references/batch-mode.md +74 -21
- package/src/skf-quick-skill/references/compile.md +30 -31
- package/src/skf-quick-skill/references/ecosystem-check.md +7 -57
- package/src/skf-quick-skill/references/finalize.md +69 -18
- package/src/skf-quick-skill/references/halt-contract.md +41 -29
- package/src/skf-quick-skill/references/health-check.md +5 -3
- package/src/skf-quick-skill/references/quick-extract.md +114 -45
- package/src/skf-quick-skill/references/registry-resolution.md +9 -64
- package/src/skf-quick-skill/references/resolve-target.md +116 -66
- package/src/skf-quick-skill/references/write-and-validate.md +79 -40
- package/src/skf-refine-architecture/SKILL.md +43 -53
- package/src/skf-refine-architecture/customize.toml +49 -20
- package/src/skf-refine-architecture/references/compile.md +97 -54
- package/src/skf-refine-architecture/references/exit-codes.md +30 -0
- package/src/skf-refine-architecture/references/finding-storage.md +21 -0
- package/src/skf-refine-architecture/references/gap-analysis.md +101 -38
- package/src/skf-refine-architecture/references/improvements.md +14 -20
- package/src/skf-refine-architecture/references/init.md +98 -57
- package/src/skf-refine-architecture/references/issue-detection.md +32 -39
- package/src/skf-refine-architecture/references/refinement-rules.md +37 -48
- package/src/skf-refine-architecture/references/report.md +65 -54
- package/src/skf-refine-architecture/scripts/skf-check-preservation.py +1619 -0
- package/src/skf-rename-skill/SKILL.md +19 -54
- package/src/skf-rename-skill/customize.toml +32 -26
- package/src/skf-rename-skill/references/execute.md +230 -184
- package/src/skf-rename-skill/references/exit-codes.md +7 -7
- package/src/skf-rename-skill/references/health-check.md +1 -7
- package/src/skf-rename-skill/references/invocation-contract.md +25 -0
- package/src/skf-rename-skill/references/report.md +63 -52
- package/src/skf-rename-skill/references/select.md +197 -115
- package/src/skf-rename-skill/scripts/skf-validate-rename-name.py +161 -21
- package/src/skf-setup/SKILL.md +26 -26
- package/src/skf-setup/customize.toml +14 -10
- package/src/skf-setup/references/auto-index.md +50 -63
- package/src/skf-setup/references/ccc-index.md +29 -90
- package/src/skf-setup/references/detect-and-tier.md +58 -67
- package/src/skf-setup/references/health-check.md +2 -0
- package/src/skf-setup/references/invocation-contract.md +14 -0
- package/src/skf-setup/references/report.md +43 -166
- package/src/skf-setup/references/tier-rules.md +5 -5
- package/src/skf-setup/references/write-config.md +34 -57
- package/src/skf-test-skill/SKILL.md +17 -57
- package/src/skf-test-skill/assets/output-section-formats.md +33 -34
- package/src/skf-test-skill/customize.toml +27 -13
- package/src/skf-test-skill/references/coherence-check.md +134 -62
- package/src/skf-test-skill/references/coverage-check-tiers.md +35 -0
- package/src/skf-test-skill/references/coverage-check.md +217 -254
- package/src/skf-test-skill/references/detect-mode.md +5 -5
- package/src/skf-test-skill/references/external-validators.md +94 -82
- package/src/skf-test-skill/references/health-check.md +6 -7
- package/src/skf-test-skill/references/init.md +163 -88
- package/src/skf-test-skill/references/invocation-contract.md +66 -0
- package/src/skf-test-skill/references/migration-section-rules.md +5 -2
- package/src/skf-test-skill/references/report.md +162 -142
- package/src/skf-test-skill/references/score.md +80 -107
- package/src/skf-test-skill/references/scoring-rules.md +41 -155
- package/src/skf-test-skill/references/source-access-protocol.md +19 -92
- package/src/skf-test-skill/references/step-hard-gate.md +51 -33
- package/src/skf-test-skill/scripts/aggregate-coherence.py +218 -30
- package/src/skf-test-skill/scripts/build-result-context.py +287 -0
- package/src/skf-test-skill/scripts/check-metadata-coherence.py +37 -4
- package/src/skf-test-skill/scripts/combine-external-scores.py +23 -6
- package/src/skf-test-skill/scripts/compute-score.py +223 -45
- package/src/skf-test-skill/scripts/gap-ledger.py +1381 -0
- package/src/skf-test-skill/scripts/hard-gate.py +203 -0
- package/src/skf-test-skill/scripts/load-coverage-inputs.py +760 -0
- package/src/skf-test-skill/scripts/locate-export-segments.py +835 -0
- package/src/skf-test-skill/scripts/reconcile-coverage.py +273 -79
- package/src/skf-test-skill/scripts/score-signatures.py +459 -0
- package/src/skf-test-skill/scripts/stage-helper-payload.py +148 -0
- package/src/skf-test-skill/scripts/validate-inventory.py +311 -16
- package/src/skf-test-skill/scripts/verify-declared-numerator.py +127 -52
- package/src/skf-test-skill/templates/test-report-template.md +21 -15
- package/src/skf-update-skill/SKILL.md +38 -25
- package/src/skf-update-skill/customize.toml +27 -12
- package/src/skf-update-skill/references/detect-changes.md +233 -222
- package/src/skf-update-skill/references/gap-driven.md +336 -0
- package/src/skf-update-skill/references/health-check.md +31 -5
- package/src/skf-update-skill/references/init.md +250 -84
- package/src/skf-update-skill/references/invocation-contract.md +12 -0
- package/src/skf-update-skill/references/manual-section-rules.md +6 -23
- package/src/skf-update-skill/references/merge.md +180 -47
- package/src/skf-update-skill/references/re-extract.md +53 -262
- package/src/skf-update-skill/references/report.md +100 -35
- package/src/skf-update-skill/references/write.md +331 -149
- package/src/skf-update-skill/scripts/skf-new-file-diff.py +29 -7
- package/src/skf-verify-stack/SKILL.md +23 -42
- package/src/skf-verify-stack/assets/feasibility-report-template.md +11 -5
- package/src/skf-verify-stack/customize.toml +55 -22
- package/src/skf-verify-stack/references/coverage-patterns.md +17 -8
- package/src/skf-verify-stack/references/coverage.md +67 -64
- package/src/skf-verify-stack/references/exit-codes.md +21 -8
- package/src/skf-verify-stack/references/init.md +107 -62
- package/src/skf-verify-stack/references/integration-verification-rules.md +12 -13
- package/src/skf-verify-stack/references/integrations.md +106 -65
- package/src/skf-verify-stack/references/report.md +59 -42
- package/src/skf-verify-stack/references/requirements.md +32 -9
- package/src/skf-verify-stack/references/synthesize.md +53 -39
- package/src/skf-verify-stack/scripts/skf-coverage-tally.py +398 -52
- package/src/skf-verify-stack/scripts/skf-previous-report.py +330 -0
- package/src/skf-verify-stack/scripts/skf-report-delta.py +453 -49
- package/src/skf-verify-stack/scripts/skf-verdict-rollup.py +240 -27
- package/tools/cli/commands/install.js +11 -4
- package/tools/cli/commands/status.js +15 -3
- package/tools/cli/commands/update.js +11 -4
- package/tools/cli/lib/tool-check.js +320 -0
- package/tools/cli/lib/version-check.js +22 -9
- package/tools/cli/skf-cli.js +4 -1
- package/.gitattributes +0 -16
- package/.nvmrc +0 -1
- package/docs/_internal/RELEASING.md +0 -679
- package/release-audits/v1.0.0-launch-audit.md +0 -728
- package/src/skf-audit-skill/references/step-doc-drift.md +0 -177
- package/src/skf-brief-skill/references/headless-source-authority-detection.md +0 -26
- package/src/skf-campaign/manifest.yaml +0 -15
- package/src/skf-create-skill/assets/tessl-dismissal-rules.md +0 -106
- package/src/skf-create-skill/references/ecosystem-check.md +0 -74
- package/src/skf-drop-skill/references/headless-contract.md +0 -18
- package/src/skf-update-skill/references/merge-conflict-rules.md +0 -15
- package/src/skf-update-skill/references/remote-source-resolution.md +0 -98
- package/src/skf-update-skill/references/validate.md +0 -124
- package/tools/validate-docs-drift.js +0 -233
- package/tools/validate-docs-links.js +0 -665
|
@@ -8,16 +8,16 @@ Rules for cross-referencing API surfaces between two skills to determine integra
|
|
|
8
8
|
|
|
9
9
|
## Verdict Definitions
|
|
10
10
|
|
|
11
|
-
Token set is defined canonically in the SKF shared feasibility report schema (`_bmad/skf/shared/references/feasibility-report-schema.md` in installed mode; `src/shared/references/feasibility-report-schema.md` in a dev checkout)
|
|
11
|
+
Token set is defined canonically in the SKF shared feasibility report schema (`{project-root}/_bmad/skf/shared/references/feasibility-report-schema.md` in installed mode; `{project-root}/src/shared/references/feasibility-report-schema.md` in a dev checkout); the table below restates the same set with this skill's evidence obligations. Tokens are case-sensitive (`Verified`, `Plausible`, `Risky`, `Blocked`); emitting any other token is a schema violation.
|
|
12
12
|
|
|
13
|
-
| Verdict
|
|
14
|
-
|
|
15
|
-
| **Verified**
|
|
16
|
-
| **Plausible** |
|
|
17
|
-
| **Risky**
|
|
18
|
-
| **Blocked**
|
|
13
|
+
| Verdict | Meaning | Required Evidence |
|
|
14
|
+
|---|---|---|
|
|
15
|
+
| **Verified** | APIs demonstrably connect and at least one skill cites the other | Check 1 (language) passes with declared evidence; Check 2 (protocol) flags no risk; Check 3 (types) passes from cited `exports` signatures; **Check 4 (docs cross-reference) passes with a literal substring/name citation** |
|
|
16
|
+
| **Plausible** | The checks pass, but neither skill cites the other | Checks 1 to 3 pass as for `Verified`; Check 4 finds no literal citation, so the Plausible cap below applies |
|
|
17
|
+
| **Risky** | Type mismatch, protocol gap, or language boundary requiring a bridge | A clear gap exists (e.g., TypeScript↔Rust FFI needed) but a workaround is architecturally feasible: cite a named workaround in the recommendation |
|
|
18
|
+
| **Blocked** | Fundamental incompatibility: no feasible integration path even with a bridge or adapter layer | The two libraries cannot exchange data in any documented way; requires replacing one of the libraries |
|
|
19
19
|
|
|
20
|
-
**
|
|
20
|
+
**Plausible cap:** when Check 4 finds no literal citation in either direction, cap the pair at `Plausible`: it can be `Plausible`, `Risky` or `Blocked`, never `Verified`. This is the only cap. Check 2 reads protocol and data-format tokens inferred from each skill's prose, so it can flag a risk, but it never promotes a pair to `Verified` and never caps one at `Plausible`. A pair whose Checks 1 to 3 pass and whose Check 4 finds a literal citation is `Verified`. This is the producer obligation the shared schema declares.
|
|
21
21
|
|
|
22
22
|
---
|
|
23
23
|
|
|
@@ -32,6 +32,7 @@ For each integration pair (Library A ↔ Library B):
|
|
|
32
32
|
|
|
33
33
|
### 2. Protocol Compatibility Check
|
|
34
34
|
|
|
35
|
+
- Input: each skill's `protocols_inferred` and `data_formats_inferred` tokens, inferred from its SKILL.md prose. Conflicting transports or formats with no adapter in the stack flag a risk. A shared or complementary token (e.g. "HTTP client" and "HTTP server"), or no token on either side, flags none: the tokens are too weak to prove compatibility, and a library pair that names no transport usually calls in-process.
|
|
35
36
|
- Matching transports are compatible modulo format alignment: both in-process → direct calls; both HTTP/REST → compatible if endpoints match; both WebSocket → check message-format compatibility; both shared-filesystem → async, check format.
|
|
36
37
|
- The load-bearing nudge: **two embedded databases may conflict on lock files — check for multi-writer support** before treating them as compatible.
|
|
37
38
|
|
|
@@ -43,11 +44,9 @@ For each integration pair (Library A ↔ Library B):
|
|
|
43
44
|
|
|
44
45
|
### 4. Documentation Cross-Reference (required for `Verified`)
|
|
45
46
|
|
|
46
|
-
- Search Skill A's SKILL.md for a literal substring/name citation of Library B
|
|
47
|
-
-
|
|
48
|
-
-
|
|
49
|
-
- A pass requires at least one literal citation in at least one direction; record the exact substring and location in the evidence block
|
|
50
|
-
- If neither skill literally cites the other, Check 4 fails and the per-pair verdict caps at `Plausible` (not `Verified`)
|
|
47
|
+
- Search Skill A's SKILL.md for a literal substring/name citation of Library B, and Skill B's SKILL.md for the reciprocal citation. The shared SKILL.md scanner runs that search (`skf-scan-skill-md-structure.py cross-reference`, integrations.md §4): a citation is a hit it lists, never a line read from a SKILL.md
|
|
48
|
+
- A hit that only matches a common word does not count (`the next step` for a skill named `next`): quote the first hit whose excerpt names the library, and a direction whose hits name only the common word has no citation
|
|
49
|
+
- A pass requires at least one literal citation in at least one direction; record the exact substring and its line in the evidence block. A fail brings the Plausible cap above into play.
|
|
51
50
|
|
|
52
51
|
---
|
|
53
52
|
|
|
@@ -1,18 +1,32 @@
|
|
|
1
1
|
---
|
|
2
2
|
nextStepFile: 'requirements.md'
|
|
3
|
-
integrationRulesData: '
|
|
4
|
-
|
|
3
|
+
integrationRulesData: 'references/integration-verification-rules.md'
|
|
4
|
+
coverageTallyScript: 'scripts/skf-coverage-tally.py'
|
|
5
5
|
feasibilitySchemaProbeOrder:
|
|
6
6
|
- '{project-root}/_bmad/skf/shared/references/feasibility-report-schema.md'
|
|
7
7
|
- '{project-root}/src/shared/references/feasibility-report-schema.md'
|
|
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
|
+
# §3 re-enumerates the skills against step 1's inventory (--expect-hashes)
|
|
12
|
+
# to find a skill that changed mid-run.
|
|
13
|
+
enumerateStackSkillsProbeOrder:
|
|
14
|
+
- '{project-root}/_bmad/skf/shared/scripts/skf-enumerate-stack-skills.py'
|
|
15
|
+
- '{project-root}/src/shared/scripts/skf-enumerate-stack-skills.py'
|
|
16
|
+
# §4 lists the literal citations between the paired skills' SKILL.md
|
|
17
|
+
# (Check 4 evidence and the cycle edges) with its cross-reference mode.
|
|
18
|
+
scanSkillMdStructureProbeOrder:
|
|
19
|
+
- '{project-root}/_bmad/skf/shared/scripts/skf-scan-skill-md-structure.py'
|
|
20
|
+
- '{project-root}/src/shared/scripts/skf-scan-skill-md-structure.py'
|
|
11
21
|
cycleFinderProbeOrder:
|
|
12
22
|
- '{project-root}/_bmad/skf/shared/scripts/skf-find-cycles.py'
|
|
13
23
|
- '{project-root}/src/shared/scripts/skf-find-cycles.py'
|
|
14
24
|
outputFile: '{outputFolderPath}/feasibility-report-{project_slug}-{timestamp}.md'
|
|
15
|
-
|
|
25
|
+
emitEnvelopeProbeOrder:
|
|
26
|
+
- '{project-root}/_bmad/skf/shared/scripts/skf-emit-result-envelope.py'
|
|
27
|
+
- '{project-root}/src/shared/scripts/skf-emit-result-envelope.py'
|
|
28
|
+
inventoryFile: '{run_dir}/skill-inventory.json'
|
|
29
|
+
docMentionsFile: '{run_dir}/doc-mentions.json'
|
|
16
30
|
---
|
|
17
31
|
|
|
18
32
|
<!-- Config: communicate in {communication_language}. Append the Integration Verdicts section to the report in {document_output_language}. -->
|
|
@@ -26,12 +40,20 @@ Cross-reference API surfaces between library pairs that the architecture documen
|
|
|
26
40
|
## Rules
|
|
27
41
|
|
|
28
42
|
- Focus only on integration pair verification using skill API surfaces
|
|
29
|
-
- Do not evaluate requirements coverage (Step 04) or
|
|
43
|
+
- Do not evaluate requirements coverage (Step 04) or read the architecture document again: step 2's mentions run holds its candidate pairs
|
|
30
44
|
- Every verdict must include evidence citations from the skills
|
|
31
45
|
|
|
32
46
|
## MANDATORY SEQUENCE
|
|
33
47
|
|
|
34
|
-
**
|
|
48
|
+
**Halt envelope.** Every HALT in this step names its exit code, `halt_reason` and phase. In headless mode, stage `{run_dir}/halt.json` as `{"phase": "<phase>", "reason": "<the halt message>", "halt_reason": "<halt_reason>", "report_path": "{outputFile}"}`, adding `"path"` when the halt names one, resolve `{emitEnvelopeHelper}` from `{emitEnvelopeProbeOrder}` if it is not bound (first existing path wins), then run:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
uv run {emitEnvelopeHelper} emit-halt --workflow skf-verify-stack --run-dir "{run_dir}" --target stderr < "{run_dir}/halt.json"
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Display the line it prints, then stop with the halt's exit code (`references/exit-codes.md` describes the envelope). If no candidate exists, or the emitter exits non-zero or prints no line, display the halt message alone. An interactive HALT displays its message and emits nothing.
|
|
55
|
+
|
|
56
|
+
**Resolve `{feasibilitySchemaRef}`** from `{feasibilitySchemaProbeOrder}`; first existing path wins (installed SKF module path first, dev-checkout `src/` fallback). The append step below uses it.
|
|
35
57
|
|
|
36
58
|
### 1. Load Integration Verification Rules
|
|
37
59
|
|
|
@@ -41,32 +63,24 @@ Extract: verification checks (language boundary, protocol compatibility, type co
|
|
|
41
63
|
|
|
42
64
|
### 2. Extract Integration Claims
|
|
43
65
|
|
|
44
|
-
**
|
|
45
|
-
|
|
46
|
-
Parse the architecture document for statements describing two or more technologies working together.
|
|
47
|
-
|
|
48
|
-
**Detection method — prose-based co-mention analysis (fallback only):**
|
|
49
|
-
- Identify sentences or paragraphs where two or more technology names appear together
|
|
50
|
-
- Look for integration verbs: "connects to", "communicates with", "wraps", "extends", "consumes", "produces", "bridges", "integrates with", "sits between"
|
|
51
|
-
- Look for data flow descriptions: "{A} sends data to {B}", "{A} results are consumed by {B}"
|
|
52
|
-
- Look for layer boundary descriptions: "{A} at the API layer connects to {B} at the data layer"
|
|
53
|
-
|
|
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.
|
|
66
|
+
**Prose co-mention:** step 2's mentions run already found the candidate pairs. Take each entry of `candidates[]` in `{docMentionsFile}` whose two skills (`a` and `b`) are both Covered in Step 02, and judge it from its `evidence[]` (`unit_excerpt`, with its `header` and `unit_line`): it is an integration claim when an entry describes an *integration relationship* (data flowing between the two, one wrapping, bridging, extending or consuming the other, or a layer boundary connecting them), not mere co-mention in the same text. A pair outside `candidates[]` is not claimed: no paragraph names both, the document only lists them together, or it draws them only in fenced code, such as a Mermaid diagram, which the mentions helper never reads.
|
|
55
67
|
|
|
56
68
|
**Build integration pairs list:**
|
|
57
69
|
- Each pair: `{library_a, library_b, architectural_context}`
|
|
58
|
-
- `architectural_context`: the quoted
|
|
70
|
+
- `architectural_context`: the quoted `unit_excerpt` of the evidence entry that shows the relationship
|
|
59
71
|
|
|
60
|
-
**Filter:** Only include pairs where BOTH libraries have a corresponding skill (Covered in Step 02). Skip pairs involving Missing skills
|
|
72
|
+
**Filter:** Only include pairs where BOTH libraries have a corresponding skill (Covered in Step 02). Skip pairs involving Missing skills: they cannot be verified. Drop a pair whose two technologies step 2 matched to the same skill: it is one library, with no integration to verify, and §5 lists it.
|
|
73
|
+
|
|
74
|
+
**Stage the pairs** for the §4 citation scan: write `{run_dir}/integration-pairs.json` as `{"pairs": [["<skill_a>", "<skill_b>"], ...]}`, naming each pair once by the two skills step 2 matched its technologies to (the Skill Match column), as `{inventoryFile}` names them. With no pair, write `{"pairs": []}`.
|
|
61
75
|
|
|
62
76
|
### 3. Load Skill API Surfaces
|
|
63
77
|
|
|
64
78
|
<!-- Subagent delegation: read SKILL.md files in parallel, return compact JSON -->
|
|
65
79
|
|
|
66
|
-
For
|
|
80
|
+
For every skill step 2 matched to a Covered technology (the Skill Match column), in an integration pair or not, delegate SKILL.md reading to a parallel subagent: step 4 maps requirements from these summaries, so no later stage reads a SKILL.md in this context. Launch up to **8 subagents concurrently**, in batches of 8 when more skills need reading (the cap keeps the aggregate token window manageable while still parallelizing typical stack sizes). Each subagent receives one skill's SKILL.md path and:
|
|
67
81
|
1. Reads the SKILL.md file
|
|
68
|
-
2. Extracts the API surface
|
|
69
|
-
3. Returns only this compact JSON
|
|
82
|
+
2. Extracts the API surface and what the library can do
|
|
83
|
+
3. Returns only this compact JSON, with no prose and no extra commentary:
|
|
70
84
|
|
|
71
85
|
```json
|
|
72
86
|
{
|
|
@@ -74,72 +88,97 @@ For each library in an integration pair, delegate SKILL.md reading to a parallel
|
|
|
74
88
|
"language": "...",
|
|
75
89
|
"exports": ["functionName(params): ReturnType", "..."],
|
|
76
90
|
"protocols_inferred": ["HTTP", "gRPC", "WebSocket", "message queue", "file I/O", "IPC"],
|
|
77
|
-
"data_formats_inferred": ["JSON", "protobuf", "CSV", "binary", "streaming"]
|
|
91
|
+
"data_formats_inferred": ["JSON", "protobuf", "CSV", "binary", "streaming"],
|
|
92
|
+
"capabilities": ["offline-first sync", "server-side rendering", "..."]
|
|
78
93
|
}
|
|
79
94
|
```
|
|
80
95
|
|
|
81
96
|
**Extraction rules for subagents:**
|
|
82
97
|
- `skill_name`, `language`: mirror the skill's metadata fields
|
|
83
98
|
- `exports`: exported functions with signatures, exported types/interfaces/classes (extracted from SKILL.md prose)
|
|
84
|
-
- `protocols_inferred`:
|
|
85
|
-
- `
|
|
99
|
+
- `protocols_inferred`, `data_formats_inferred`: protocol and format tokens mentioned in the SKILL.md descriptions and examples
|
|
100
|
+
- `capabilities`: up to 10 short phrases naming what the library does, from the SKILL.md description and its sections (the requirements stage matches each requirement against them)
|
|
86
101
|
- If a field has no matches, return an empty array `[]`
|
|
87
102
|
|
|
88
|
-
**
|
|
103
|
+
**When subagents are unavailable**, read the SKILL.md files yourself, one at a time and in the same order: for each skill, read its SKILL.md, write its compact JSON by the rules above and append it to `{run_dir}/skill-summaries.json` at once, then go on to the next. The 20% budget below counts subagent replies only.
|
|
104
|
+
|
|
105
|
+
**These two lists are inferred from prose, not declared** (no skill's `metadata.json` has `protocols` or `data_formats`), so they are weak evidence: Check 2 reads them as `{integrationRulesData}` says.
|
|
106
|
+
|
|
107
|
+
**Schema validation (parent):** Each subagent response must contain the required keys (`skill_name`, `language`, `exports`, `capabilities`). Reject responses missing required keys and exclude that skill from pair evaluation and from the requirements stage; if more than **20%** of subagent calls return malformed JSON, HALT (exit code 7, `halt_reason: "inventory-unreliable"`) at phase `integrations:api-surfaces` with "API-surface extraction unreliable: more than 20% of subagent reads returned malformed JSON. Re-run [VS] after skills stabilize."
|
|
89
108
|
|
|
90
|
-
**
|
|
109
|
+
**Parent collects all JSON summaries.** Apart from the one-at-a-time reads of the sequential fallback, never load a full SKILL.md into the parent context. Append the accepted summaries of each batch to `{run_dir}/skill-summaries.json`, one JSON array, as the batch returns: the requirements stage reads them from there, so they survive context compaction.
|
|
91
110
|
|
|
92
|
-
**
|
|
111
|
+
**From `skill_inventory` (step 1 §2), also take** each skill's `language` (a string, or a list for a stack; it is authoritative and overrides the subagent's `language` when the two disagree), `exports` (empty for a stack skill) and `exports_documented` (the export count), reading them from `{inventoryFile}`. The enumerate helper read them from `metadata.json`, so the parent never opens it.
|
|
112
|
+
|
|
113
|
+
**Mid-run change check.** Resolve `{enumerateStackSkillsHelper}` from `{enumerateStackSkillsProbeOrder}`; first existing path wins. Re-enumerate against the inventory step 1 wrote, which compares each skill's `metadata_hash` with the one recorded then:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
uv run {enumerateStackSkillsHelper} enumerate {skills_output_folder} --expect-hashes "{inventoryFile}" > "{run_dir}/inventory-recheck.json"
|
|
117
|
+
```
|
|
93
118
|
|
|
94
|
-
|
|
95
|
-
- `language` — primary programming language (authoritative — overrides subagent `language` if they disagree)
|
|
96
|
-
- `exports` — export names array (populated for individual skills; empty for stack skills)
|
|
97
|
-
- `stats.exports_documented` — export count
|
|
98
|
-
- `confidence_tier` — extraction confidence level
|
|
119
|
+
If no candidate exists, or the command exits non-zero, HALT (exit code 3, `halt_reason: "resolution-failure"`) at phase `integrations:change-check`. Read only its `changed_skills` and `missing_skills`: a pair involving one of those skills is not rated. Its row in every table and in `verdict-rows.json` (§4) carries the verdict `Risky` and the rationale "skill modified mid-run: re-run [VS]", and each such skill is recorded once in the run sink:
|
|
99
120
|
|
|
100
|
-
|
|
121
|
+
```bash
|
|
122
|
+
uv run {emitEnvelopeHelper} record --run-dir "{run_dir}" --warning 'skill_modified_mid_run: <skill>'
|
|
123
|
+
```
|
|
101
124
|
|
|
102
|
-
|
|
125
|
+
The recheck's `new_skills` appeared after step 1 and are not part of this run.
|
|
103
126
|
|
|
104
127
|
### 4. Cross-Reference Each Integration Pair
|
|
105
128
|
|
|
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):
|
|
129
|
+
For each integration pair `{library_a, library_b}`, run the four-check protocol and assign the per-pair verdict per `{integrationRulesData}` (loaded in §1): its Cross-Reference Protocol defines Checks 1 to 4, and its Verdict Definitions define the four verdicts and the Plausible cap. Apply them as written there. Check 2 reads the `protocols_inferred` / `data_formats_inferred` lists from §3.
|
|
130
|
+
|
|
131
|
+
**Run the citation scan once**, before rating the first pair. Resolve `{scanSkillMdStructureHelper}` from `{scanSkillMdStructureProbeOrder}`; first existing path wins. Then run:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
uv run {scanSkillMdStructureHelper} cross-reference --skills "{inventoryFile}" --skills-root "{skills_output_folder}" --pairs "{run_dir}/integration-pairs.json" > "{run_dir}/citations.json"
|
|
135
|
+
```
|
|
107
136
|
|
|
108
|
-
|
|
137
|
+
If no candidate exists, or the command exits non-zero, HALT (exit code 3, `halt_reason: "resolution-failure"`) at phase `integrations:citations`, naming its first stderr line. Check 4 reads each citing direction of `citations[]` in `{run_dir}/citations.json`: `from`, `to` and its `hits[]`, each with its `line`, the `substring` as written and an `excerpt`. Its `warnings[]` name a SKILL.md the scanner could not read, whose skill then cites nothing.
|
|
109
138
|
|
|
110
139
|
**Each verdict includes:**
|
|
111
140
|
- Which checks passed and which flagged
|
|
112
141
|
- Evidence citations: specific exports, types, or literal substrings from the skills
|
|
113
|
-
- `
|
|
114
|
-
- For `
|
|
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.
|
|
142
|
+
- For `Verified`: the Check 4 citation from `{run_dir}/citations.json`, its `substring` and `line` in the citing skill's SKILL.md with the hit's `excerpt` (e.g., `"react-query"` at line 42 of `next`'s SKILL.md)
|
|
143
|
+
- **Tier annotation:** For each contributing skill, append `(evidence from a {evidence_tier} skill)` with that skill's `evidence_tier` from `skill_inventory` (e.g., `(evidence from a T1 skill)`), so reviewers weigh the evidence by the tier its skill rests on.
|
|
116
144
|
|
|
117
|
-
**Cycle detection (after all pairs evaluated):**
|
|
145
|
+
**Cycle detection (after all pairs evaluated):** an edge `A → B` exists when skill A literally cites skill B (Check 4). Two skills that cite each other are not a cycle: their mutual citation is Check 4 evidence for their own pair, and a loop built only from such pairs is no cycle either. 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
146
|
|
|
119
|
-
1. **
|
|
120
|
-
2. **Resolve `{cycleFinderHelper}`** from `{cycleFinderProbeOrder}`; first existing path wins. Enumerate cycles deterministically (run `uv run {cycleFinderHelper} find --help` for the contract):
|
|
147
|
+
1. **Record the rejected directions:** write `{run_dir}/rejected-edges.json` as `{"edges": [["<from>", "<to>"], ...]}`, one entry per citing direction of `{run_dir}/citations.json` whose every hit Check 4 rejected as a common word, and `{"edges": []}` when it rejected none.
|
|
148
|
+
2. **Resolve `{cycleFinderHelper}`** from `{cycleFinderProbeOrder}`; first existing path wins. If no candidate exists: HALT (exit code 3, `halt_reason: "resolution-failure"`) at phase `integrations:cycles`. Enumerate cycles deterministically (run `uv run {cycleFinderHelper} find --help` for the contract):
|
|
121
149
|
|
|
122
150
|
```bash
|
|
123
|
-
uv run {cycleFinderHelper} find --edges -
|
|
151
|
+
uv run {cycleFinderHelper} find --edges "{run_dir}/citations.json" --exclude-edges "{run_dir}/rejected-edges.json" --skip-mutual > "{run_dir}/cycles.json"
|
|
124
152
|
```
|
|
125
|
-
|
|
153
|
+
It reads the `edges` of the citations file (one `[from, to]` pair per citing direction), leaves out the rejected directions and every cycle whose edges are all mutual citations, and writes:
|
|
126
154
|
```json
|
|
127
155
|
{"cycles": [["A", "B", "C", "A"], ...], "cycle_count": N}
|
|
128
156
|
```
|
|
129
|
-
Each `cycles[]` entry is a closed node path (first node repeated at the end); every
|
|
157
|
+
Each `cycles[]` entry is a closed node path (first node repeated at the end) through three or more skills, with at least one one-way citation; every such cycle appears exactly once, de-duplicated across rotations. With no pair it writes an empty list.
|
|
158
|
+
3. **For each cycle** in `cycles[]`, the canonical table holds one more `Risky` row, which §6 renders after the pair rows. Its `lib_a`, `cycle`, keeps the row apart from every pair row, since the next run's delta keys rows on their two libraries. Leave the pair verdicts as they are.
|
|
159
|
+
|
|
160
|
+
**Count the verdicts deterministically.** Rating each pair is judgment; counting the rows of the canonical table has one correct answer, so delegate it. Write `{run_dir}/verdict-rows.json` as `{"rows": [{"lib_a": "…", "lib_b": "…", "verdict": "Verified|Plausible|Risky|Blocked", "rationale": "<the checks and evidence behind the verdict, one line>"}, …]}`, one row per pair and no cycle row (§6 renders the canonical rows from it), and run:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
uv run {coverageTallyScript} --kind integrations --cycles "{run_dir}/cycles.json" --stdin < "{run_dir}/verdict-rows.json"
|
|
164
|
+
```
|
|
130
165
|
|
|
131
|
-
|
|
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.
|
|
166
|
+
It returns `pairs_verified`, `pairs_plausible`, `pairs_risky` (each cycle counted as one `Risky` row), `pairs_blocked`, `pair_count`, `cycle_count` and `row_count` (run `uv run {coverageTallyScript} --help` for the contract). When it exits non-zero, it rejected its input and says why (its JSON `error`): fix the rows and run it again. Section 5 displays these counts and section 6 persists them.
|
|
133
167
|
|
|
134
168
|
### 5. Display Integration Results
|
|
135
169
|
|
|
170
|
+
The Summary line shows the §4 tally's counts (`pairs_risky` includes each cycle row).
|
|
171
|
+
|
|
136
172
|
"**Pass 2: Integration Verification**
|
|
137
173
|
|
|
138
|
-
| Library A | Library B | Context |
|
|
139
|
-
|
|
140
|
-
| {lib_a} | {lib_b} | {brief context} | {
|
|
174
|
+
| Library A | Library B | Context | Verdict | Evidence |
|
|
175
|
+
|-----------|-----------|---------|---------|----------|
|
|
176
|
+
| {lib_a} | {lib_b} | {brief context} | {Verified/Plausible/Risky/Blocked} | {key evidence, including Check 4 literal citation if Verified} |
|
|
177
|
+
|
|
178
|
+
**Summary:** {pairs_verified} Verified, {pairs_plausible} Plausible, {pairs_risky} Risky, {pairs_blocked} Blocked
|
|
141
179
|
|
|
142
|
-
|
|
180
|
+
{IF §2 dropped a pair whose technologies are one skill:}
|
|
181
|
+
**Not verified (one skill):** `{tech_a}` and `{tech_b}` both match `{skill}`, so there is no integration between two skills to check.
|
|
143
182
|
|
|
144
183
|
{IF zero integration pairs found:}
|
|
145
184
|
**No integration claims detected in the architecture document prose.** Ensure your architecture document describes relationships between technologies in text form (not exclusively in Mermaid diagrams). Coverage-only analysis was performed.
|
|
@@ -156,27 +195,29 @@ For each integration pair `{library_a, library_b}`, run the four-check protocol
|
|
|
156
195
|
|
|
157
196
|
### 6. Append to Report
|
|
158
197
|
|
|
159
|
-
**Resolve `{atomicWriteHelper}`** from `{atomicWriteProbeOrder}`; first existing path wins. If no candidate exists: HALT (exit code 3, `halt_reason: "resolution-failure"`)
|
|
198
|
+
**Resolve `{atomicWriteHelper}`** from `{atomicWriteProbeOrder}`; first existing path wins. If no candidate exists: HALT (exit code 3, `halt_reason: "resolution-failure"`) at phase `integrations:report`.
|
|
160
199
|
|
|
161
|
-
Write the **Integration Verdicts** section
|
|
162
|
-
-
|
|
163
|
-
- Include the extended table with Context, Source, and Evidence columns below it
|
|
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)
|
|
165
|
-
- Update frontmatter: append `'integrations'` to `stepsCompleted`; set `pairsVerified`, `pairsPlausible`, `pairsRisky`, `pairsBlocked` counts
|
|
166
|
-
- Pipe the updated full content through `python3 {atomicWriteHelper} write --target {outputFile}` and again with `--target {outputFileLatest}`
|
|
200
|
+
Write the **Integration Verdicts** section of `{outputFile}`. The report template already holds the canonical table under `## Integration Verdicts`: the header `| lib_a | lib_b | verdict | rationale |` (per `{feasibilitySchemaRef}`) and its delimiter row. Consumers read that table and reject a report that holds it twice, so fill it in place instead of appending another one:
|
|
201
|
+
- Render its rows from the §4 rows file and the cycles, one per pair and one per §4 cycle, each verdict a schema token and each rationale kept in its cell:
|
|
167
202
|
|
|
168
|
-
|
|
203
|
+
```bash
|
|
204
|
+
uv run {coverageTallyScript} --kind integrations --render --cycles "{run_dir}/cycles.json" --stdin < "{run_dir}/verdict-rows.json"
|
|
205
|
+
```
|
|
169
206
|
|
|
170
|
-
|
|
207
|
+
Put the lines it prints under the template's header, as printed; on a non-zero exit, fix the row its JSON `error` names and run it again. With zero integration pairs, leave the table with its header and delimiter rows only.
|
|
208
|
+
- After one blank line, add the display table with the extra Context and Evidence columns for human readers (a separate table, so consumers skip it).
|
|
209
|
+
- Include recommendations for Risky and Blocked pairs (a Blocked one that proposes a replacement names at least one alternative library with a one-line justification, or says no named candidate was found and gives the selection criteria)
|
|
210
|
+
- Update frontmatter: append `'integrations'` to `stepsCompleted`; from the §4 tally, set `pairsVerified` ← `pairs_verified`, `pairsPlausible` ← `pairs_plausible`, `pairsRisky` ← `pairs_risky` (each cycle row included) and `pairsBlocked` ← `pairs_blocked`
|
|
211
|
+
- Pipe the updated full content through `python3 {atomicWriteHelper} write --target {outputFile}`. On a non-zero exit: HALT (exit code 4, `halt_reason: "write-failed"`) at phase `integrations:report`, with `"path": "{outputFile}"`.
|
|
171
212
|
|
|
172
|
-
|
|
213
|
+
### 7. Auto-Proceed to Next Step
|
|
173
214
|
|
|
174
|
-
|
|
175
|
-
- If C: continue.
|
|
215
|
+
{IF the §4 tally's `pair_count` is not 0 and its `pairs_blocked` equals `pair_count` (every pair is Blocked):} display one warning line (headless: log it), record it in the run sink, and continue, so synthesize can recommend a way past each Blocked pair: "**Warning:** every integration pair is Blocked; the run will resolve to `NOT_FEASIBLE`, and the report will name a replacement library or a bridge for each Blocked pair."
|
|
176
216
|
|
|
177
|
-
|
|
217
|
+
```bash
|
|
218
|
+
uv run {emitEnvelopeHelper} record --run-dir "{run_dir}" --warning 'all_pairs_blocked: every integration pair is Blocked'
|
|
219
|
+
```
|
|
178
220
|
|
|
179
221
|
"**Proceeding to requirements verification...**"
|
|
180
222
|
|
|
181
223
|
Load, read the full file and then execute `{nextStepFile}`.
|
|
182
|
-
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
---
|
|
2
|
-
# {outputFile} and {outputFileLatest} resolve from
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
# so every stage sees the same path.
|
|
2
|
+
# {outputFile} and {outputFileLatest} resolve from {timestamp} (fixed in
|
|
3
|
+
# SKILL.md On Activation §2), {project_slug} (bound at the top of init.md)
|
|
4
|
+
# and {outputFolderPath} (On Activation §4), with the same template as the
|
|
5
|
+
# init.md frontmatter, so every stage sees the same path. §1 is the only
|
|
6
|
+
# place that writes {outputFileLatest}: once the report passes its check.
|
|
6
7
|
outputFile: '{outputFolderPath}/feasibility-report-{project_slug}-{timestamp}.md'
|
|
7
8
|
outputFileLatest: '{outputFolderPath}/feasibility-report-{project_slug}-latest.md'
|
|
8
9
|
feasibilitySchemaProbeOrder:
|
|
@@ -14,6 +15,9 @@ atomicWriteProbeOrder:
|
|
|
14
15
|
validateFeasibilityReportProbeOrder:
|
|
15
16
|
- '{project-root}/_bmad/skf/shared/scripts/skf-validate-feasibility-report.py'
|
|
16
17
|
- '{project-root}/src/shared/scripts/skf-validate-feasibility-report.py'
|
|
18
|
+
emitEnvelopeProbeOrder:
|
|
19
|
+
- '{project-root}/_bmad/skf/shared/scripts/skf-emit-result-envelope.py'
|
|
20
|
+
- '{project-root}/src/shared/scripts/skf-emit-result-envelope.py'
|
|
17
21
|
nextStepFile: 'health-check.md'
|
|
18
22
|
---
|
|
19
23
|
|
|
@@ -23,7 +27,7 @@ nextStepFile: 'health-check.md'
|
|
|
23
27
|
|
|
24
28
|
## STEP GOAL:
|
|
25
29
|
|
|
26
|
-
Present the complete feasibility report to the user. Display the overall verdict prominently, walk through key findings from each analysis pass, present actionable next steps based on the verdict,
|
|
30
|
+
Present the complete feasibility report to the user. Display the overall verdict prominently, walk through key findings from each analysis pass, present actionable next steps based on the verdict, write the result contract, and finish.
|
|
27
31
|
|
|
28
32
|
## Rules
|
|
29
33
|
|
|
@@ -32,30 +36,43 @@ Present the complete feasibility report to the user. Display the overall verdict
|
|
|
32
36
|
|
|
33
37
|
## MANDATORY SEQUENCE
|
|
34
38
|
|
|
39
|
+
**Halt envelope.** Every HALT in this step names its exit code, `halt_reason` and phase. In headless mode, stage `{run_dir}/halt.json` as `{"phase": "<phase>", "reason": "<the halt message>", "halt_reason": "<halt_reason>", "report_path": "{outputFile}"}`, adding `"path"` when the halt names one, resolve `{emitEnvelopeHelper}` from `{emitEnvelopeProbeOrder}` if it is not bound (first existing path wins), then run:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
uv run {emitEnvelopeHelper} emit-halt --workflow skf-verify-stack --run-dir "{run_dir}" --target stderr < "{run_dir}/halt.json"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Display the line it prints, then stop with the halt's exit code (`references/exit-codes.md` describes the envelope). If no candidate exists, or the emitter exits non-zero or prints no line, display the halt message alone. An interactive HALT displays its message and emits nothing.
|
|
46
|
+
|
|
35
47
|
### 1. Load Complete Report
|
|
36
48
|
|
|
37
49
|
Read the entire `{outputFile}` to have all data available for presentation.
|
|
38
50
|
|
|
39
51
|
**Resolve `{feasibilitySchemaRef}`** from `{feasibilitySchemaProbeOrder}`; first existing path wins (installed SKF module path first, dev-checkout `src/` fallback).
|
|
40
52
|
|
|
41
|
-
**Validate report
|
|
53
|
+
**Validate the report (deterministic gate).** Resolve `{validateFeasibilityReportHelper}` from `{validateFeasibilityReportProbeOrder}`; first existing path wins (installed SKF module path first, dev-checkout `src/` fallback). If no candidate exists: HALT (exit code 3, `halt_reason: "resolution-failure"`) at phase `report:check`. Then run:
|
|
42
54
|
|
|
43
55
|
```bash
|
|
44
|
-
|
|
56
|
+
uv run {validateFeasibilityReportHelper} "{outputFile}" -o "{run_dir}/report-check.json"
|
|
45
57
|
```
|
|
46
58
|
|
|
47
|
-
The script (see `--help`)
|
|
59
|
+
The script (see `--help`) checks the report against `{feasibilitySchemaRef}`: the five required body sections (`## Executive Summary`, `## Coverage Analysis`, `## Integration Verdicts`, `## Recommendations`, `## Evidence Sources`) in canonical order, frontmatter `schemaVersion == "1.0"`, and whatever else its `--help` lists. It writes a JSON verdict to `{run_dir}/report-check.json` (`violation` names the class; the detail fields say what failed; `overallVerdict` and `coveragePercentage` are the report's own) and exits `0` when valid, `1` on a schema violation, `2` when the report cannot be read.
|
|
48
60
|
|
|
49
|
-
|
|
61
|
+
On any non-zero exit, HALT (exit code 5, `halt_reason: "schema-violation"`) at phase `report:check`: do not display partial results, and leave `{outputFileLatest}` as it is. Report the specific violation from the JSON:
|
|
50
62
|
|
|
51
|
-
|
|
63
|
+
- a missing or out-of-order section (`missingHeadings` / `orderViolations`);
|
|
64
|
+
- a schemaVersion mismatch: "Report frontmatter schemaVersion `{schemaVersionFound}` does not match producer schema `1.0`: report was corrupted between steps. Re-run [VS]." (The producer never proceeds past a schema mismatch.)
|
|
65
|
+
- any other detail the JSON carries, such as a missing or doubled canonical verdict table or an unknown verdict token.
|
|
52
66
|
|
|
53
|
-
|
|
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.)
|
|
67
|
+
**Publish the checked report.** With the gate passed, resolve `{atomicWriteHelper}` from `{atomicWriteProbeOrder}` (first existing path wins; if no candidate exists: HALT (exit code 3, `halt_reason: "resolution-failure"`) at phase `report:publish`) and copy the report over its stable `-latest` copy, which consumers such as campaign, create-stack-skill and refine-architecture read:
|
|
55
68
|
|
|
56
|
-
|
|
69
|
+
```bash
|
|
70
|
+
python3 {atomicWriteHelper} write --target "{outputFileLatest}" < "{outputFile}"
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
It is a copy, not a symlink (per the shared schema). This is the run's only write of `{outputFileLatest}`: every stage before this one wrote only `{outputFile}`, so a run that halted earlier left the previous finished report at the stable path. On a non-zero exit: HALT (exit code 4, `halt_reason: "write-failed"`) at phase `report:publish`, with `"path": "{outputFileLatest}"`; the atomic write leaves the previous copy intact.
|
|
57
74
|
|
|
58
|
-
With the deterministic gate passed
|
|
75
|
+
With the deterministic gate passed, **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.
|
|
59
76
|
|
|
60
77
|
### 2. Present Summary
|
|
61
78
|
|
|
@@ -88,52 +105,52 @@ With the deterministic gate passed (sections present + in order, `schemaVersion
|
|
|
88
105
|
|
|
89
106
|
### 3. Present Detailed Findings
|
|
90
107
|
|
|
91
|
-
Walk through the highlights
|
|
108
|
+
Walk through the highlights: coverage gaps, risky/blocked integrations, and partial/unaddressed requirements (when a PRD pass ran). Cite specific items by name; cap at the top ~5 per category to keep the summary scannable. The full detail is in `{outputFile}`.
|
|
92
109
|
|
|
93
110
|
### 4. Present Next Steps
|
|
94
111
|
|
|
95
112
|
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:
|
|
96
113
|
|
|
97
|
-
- **`FEASIBLE`:** "**Your stack is verified.**
|
|
114
|
+
- **`FEASIBLE`:** "**Your stack is verified.**" Then give the verdict rationale from the report's `## Executive Summary`: synthesize wrote there what was verified, including when there was no integration pair to verify.
|
|
98
115
|
- **`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
116
|
- **`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.
|
|
100
117
|
|
|
101
118
|
### 4b. Result Contract
|
|
102
119
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
120
|
+
The shared emitter writes the result contract (per `shared/references/output-contract-schema.md`, which resolves relative to the SKF module root: `{project-root}/_bmad/skf/` when installed, `{project-root}/src/` during development) and prints the envelope; this step stages their content, every count from a file a helper wrote. Write `{run_dir}/result-context.json`:
|
|
121
|
+
|
|
122
|
+
```json
|
|
123
|
+
{
|
|
124
|
+
"status": "success",
|
|
125
|
+
"report_path": "{outputFile}",
|
|
126
|
+
"report_latest_path": "{outputFileLatest}",
|
|
127
|
+
"overall_verdict": "<overallVerdict>",
|
|
128
|
+
"coverage_percentage": <coveragePercentage>,
|
|
129
|
+
"recommendation_count": <recommendationCount>,
|
|
130
|
+
"result_contract": {
|
|
131
|
+
"skill": "skf-verify-stack",
|
|
132
|
+
"status": "success",
|
|
133
|
+
"outputs": [{"type": "report", "path": "{outputFile}"}, {"type": "report", "path": "{outputFileLatest}"}],
|
|
134
|
+
"summary": {"overallVerdict": "<overallVerdict>", "coveragePercentage": <coveragePercentage>, "recommendationCount": <recommendationCount>}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
113
137
|
```
|
|
114
138
|
|
|
115
|
-
`
|
|
139
|
+
`<overallVerdict>` and `<coveragePercentage>` are the `overallVerdict` (a case-sensitive schema token: `FEASIBLE`, `CONDITIONALLY_FEASIBLE` or `NOT_FEASIBLE`) and `coveragePercentage` §1's check read into `{run_dir}/report-check.json`; `<recommendationCount>` is the report frontmatter's `recommendationCount`, the count synthesize took from its verdict rollup. Then run, in every mode (the emitter writes result files only into a folder that exists):
|
|
116
140
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
141
|
+
```bash
|
|
142
|
+
mkdir -p "{forge_data_folder}" || uv run {emitEnvelopeHelper} record --run-dir "{run_dir}" --warning 'result_file_write_failed: cannot create the forge data folder'
|
|
143
|
+
uv run {emitEnvelopeHelper} emit --workflow skf-verify-stack --run-dir "{run_dir}" --result-dir "{forge_data_folder}" < "{run_dir}/result-context.json"
|
|
144
|
+
```
|
|
120
145
|
|
|
121
|
-
|
|
146
|
+
It writes `{forge_data_folder}/verify-stack-result-{timestamp}.json`, named after the run's own `{timestamp}` (the one the timestamped report carries), and its `verify-stack-result-latest.json` copy, and prints the `SKF_VERIFY_STACK_RESULT_JSON:` line on stdout. When `{headless_mode}` is true, display the line verbatim before chaining to step 7. A result file that could not be written leaves `result_path` null and a `result_file_write_failed` warning in the line, and the run still finishes. If the emitter exits non-zero, correct `result-context.json` from the message on its stderr and run it once more; if it fails again, HALT (exit code 4, `halt_reason: "write-failed"`) at phase `report:result-contract`, adding `"report_latest_path": "{outputFileLatest}"` to the halt payload: the run's result contract could not be written.
|
|
122
147
|
|
|
123
|
-
|
|
148
|
+
### 5. Finish
|
|
124
149
|
|
|
125
|
-
|
|
126
|
-
- **IF X:** "**Feasibility report saved to:** `{outputFile}`
|
|
150
|
+
"**Feasibility report saved to:** `{outputFile}` (a copy at `{outputFileLatest}`). Ask me to walk through any section of it.
|
|
127
151
|
|
|
128
152
|
Re-run **[VS] Verify Stack** anytime after making changes to your skills or architecture document.
|
|
129
153
|
|
|
130
154
|
**Verification workflow complete.**"
|
|
131
155
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
#### EXECUTION RULES:
|
|
135
|
-
|
|
136
|
-
- **GATE [default: X]** — If `{headless_mode}`: auto-proceed with [X] Exit verification, log: "headless: auto-exit past report menu"
|
|
137
|
-
- R may be selected multiple times — always walk through the full report
|
|
138
|
-
|
|
139
|
-
|
|
156
|
+
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 delete the run folder, whose inventory, summaries and payloads the run no longer needs: `rm -rf "{run_dir}"`. Then load, read the full file, and execute `{nextStepFile}`: the health-check step is the true terminal step of this workflow.
|