bmad-module-skill-forge 2.2.0 → 4.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 +143 -18
- package/docs/verifying-a-skill.md +87 -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 +3 -3
- 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 +31 -59
- 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 +233 -64
- package/src/shared/scripts/skf-build-change-manifest.py +2753 -28
- 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 +772 -0
- package/src/shared/scripts/skf-comention-pairs.py +1333 -123
- package/src/shared/scripts/skf-compare-file-hashes.py +267 -105
- 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 +21 -3
- 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 +197 -55
- 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 +5247 -96
- package/src/shared/scripts/skf-extraction-inventory.py +1280 -0
- package/src/shared/scripts/skf-extraction-snapshot.py +664 -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 +469 -205
- package/src/shared/scripts/skf-github-fetch.py +365 -0
- package/src/shared/scripts/skf-github-probe.py +700 -0
- package/src/shared/scripts/skf-hash-content.py +180 -20
- package/src/shared/scripts/skf-language-corpora.py +1 -1
- package/src/shared/scripts/skf-load-provenance.py +161 -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 +143 -20
- 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 +176 -28
- package/src/shared/scripts/skf-promote-staged.py +430 -0
- package/src/shared/scripts/skf-provenance-gap-dispatch.py +64 -8
- 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 +155 -14
- 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 +787 -121
- package/src/shared/scripts/skf-tessl-review.py +706 -0
- package/src/shared/scripts/skf-update-active-symlink.py +120 -67
- 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 +23 -2
- 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 +3945 -152
- package/src/shared/scripts/skf-write-skill-brief.py +406 -25
- 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 +28 -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/health-check.md +2 -0
- package/src/skf-audit-skill/references/init.md +149 -210
- package/src/skf-audit-skill/references/re-index.md +103 -110
- package/src/skf-audit-skill/references/report.md +96 -33
- package/src/skf-audit-skill/references/semantic-diff.md +34 -25
- 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 +80 -90
- package/src/skf-audit-skill/references/upstream-checkout.md +77 -0
- package/src/skf-audit-skill/scripts/render-drift-tables.py +712 -0
- package/src/skf-brief-skill/SKILL.md +37 -26
- package/src/skf-brief-skill/assets/description-voice-examples.md +1 -1
- package/src/skf-brief-skill/assets/scope-templates.md +18 -25
- package/src/skf-brief-skill/assets/skill-brief-schema.md +30 -23
- package/src/skf-brief-skill/customize.toml +48 -20
- package/src/skf-brief-skill/references/analyze-target.md +144 -127
- package/src/skf-brief-skill/references/confirm-brief.md +11 -9
- 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 +26 -100
- package/src/skf-brief-skill/references/step-auto-validate.md +20 -121
- package/src/skf-brief-skill/references/version-resolution.md +7 -10
- 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 +11 -8
- package/src/skf-create-skill/assets/skill-sections.md +21 -11
- package/src/skf-create-skill/customize.toml +20 -8
- package/src/skf-create-skill/references/authoritative-files-protocol.md +36 -58
- 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 +119 -70
- 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 +37 -0
- package/src/skf-create-skill/references/extract.md +204 -162
- package/src/skf-create-skill/references/extraction-patterns-by-hand.md +141 -0
- package/src/skf-create-skill/references/extraction-patterns-tracing.md +11 -11
- package/src/skf-create-skill/references/extraction-patterns.md +588 -201
- 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 +37 -57
- package/src/skf-create-skill/references/source-resolution-protocols.md +58 -169
- 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 +83 -146
- package/src/skf-drop-skill/references/health-check.md +2 -0
- 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 +122 -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 +209 -264
- 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 +164 -91
- 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 +164 -142
- package/src/skf-test-skill/references/score.md +80 -107
- package/src/skf-test-skill/references/scoring-rules.md +42 -155
- package/src/skf-test-skill/references/source-access-protocol.md +18 -94
- 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 +380 -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 +1666 -0
- package/src/skf-test-skill/scripts/hard-gate.py +203 -0
- package/src/skf-test-skill/scripts/load-coverage-inputs.py +1198 -0
- package/src/skf-test-skill/scripts/locate-export-segments.py +835 -0
- package/src/skf-test-skill/scripts/reconcile-coverage.py +547 -79
- package/src/skf-test-skill/scripts/score-signatures.py +479 -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 +133 -56
- 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 +253 -223
- 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 +254 -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 +182 -49
- package/src/skf-update-skill/references/re-extract.md +53 -262
- package/src/skf-update-skill/references/report.md +102 -35
- package/src/skf-update-skill/references/write.md +357 -155
- package/src/skf-update-skill/scripts/skf-new-file-diff.py +183 -46
- 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
|
@@ -6,9 +6,6 @@ validateBriefSchemaProbeOrder:
|
|
|
6
6
|
writeSkillBriefProbeOrder:
|
|
7
7
|
- '{project-root}/_bmad/skf/shared/scripts/skf-write-skill-brief.py'
|
|
8
8
|
- '{project-root}/src/shared/scripts/skf-write-skill-brief.py'
|
|
9
|
-
emitBriefEnvelopeProbeOrder:
|
|
10
|
-
- '{project-root}/_bmad/skf/shared/scripts/skf-emit-brief-result-envelope.py'
|
|
11
|
-
- '{project-root}/src/shared/scripts/skf-emit-brief-result-envelope.py'
|
|
12
9
|
mergeDocUrlsProbeOrder:
|
|
13
10
|
- '{project-root}/_bmad/skf/shared/scripts/skf-merge-doc-urls.py'
|
|
14
11
|
- '{project-root}/src/shared/scripts/skf-merge-doc-urls.py'
|
|
@@ -23,7 +20,7 @@ detectDocsProbeOrder:
|
|
|
23
20
|
|
|
24
21
|
## STEP GOAL:
|
|
25
22
|
|
|
26
|
-
To enrich an upstream skill brief (produced by AN auto-scope) with documentation URLs discovered via `skf-detect-docs.py`, validate the enriched brief, and write it through the canonical writer. Envelope emission is deferred to step-auto-validate.md, which
|
|
23
|
+
To enrich an upstream skill brief (produced by AN auto-scope) with documentation URLs discovered via `skf-detect-docs.py`, validate the enriched brief, and write it through the canonical writer. Envelope emission is deferred to step-auto-validate.md, which checks the written brief and summarizes it first. This step replaces the interactive gather-intent → analyze-target → scope-definition → confirm-brief → write-brief chain when `[auto]` mode is active.
|
|
27
24
|
|
|
28
25
|
## Rules
|
|
29
26
|
|
|
@@ -40,9 +37,7 @@ To enrich an upstream skill brief (produced by AN auto-scope) with documentation
|
|
|
40
37
|
|
|
41
38
|
Read the upstream brief path from `{brief_path}` (passed by the forger from AN's `SKF_ANALYZE_RESULT_JSON` `brief_paths[]`).
|
|
42
39
|
|
|
43
|
-
**IF `{brief_path}` is not set or the file does not exist:**
|
|
44
|
-
- HARD HALT with exit code 2 (`input-missing`): "**Auto-brief requires an upstream brief — `brief_path` is missing or the file does not exist at `{brief_path}`.**"
|
|
45
|
-
- Emit error envelope per §6 with `halt_reason: "input-missing"`.
|
|
40
|
+
**IF `{brief_path}` is not set or the file does not exist:** emit the halt envelope first, `uv run {emitBriefEnvelopeHelper} emit --target stderr` with `halt_reason: "input-missing"` (SKILL.md Halt Contract), then HARD HALT (exit code 2): "**Auto-brief requires an upstream brief: `brief_path` is missing or the file does not exist at `{brief_path}`.**"
|
|
46
41
|
|
|
47
42
|
**Resolve `{validateBriefSchemaHelper}`** from `{validateBriefSchemaProbeOrder}`; first existing path wins. HALT if no candidate exists.
|
|
48
43
|
|
|
@@ -54,131 +49,62 @@ uv run {validateBriefSchemaHelper} {brief_path}
|
|
|
54
49
|
|
|
55
50
|
The script returns JSON `{valid, errors[], warnings[], halt_reason, brief}`.
|
|
56
51
|
|
|
57
|
-
- **`valid: false
|
|
58
|
-
- **`valid: true
|
|
52
|
+
- **`valid: false`**: the upstream brief is malformed. Emit the halt envelope first, `uv run {emitBriefEnvelopeHelper} emit --target stderr` with `halt_reason: "input-invalid"` (SKILL.md Halt Contract), then HARD HALT (exit code 2): "**Upstream brief at `{brief_path}` is invalid: {first error message}.**"
|
|
53
|
+
- **`valid: true`**: proceed with the parsed `brief` payload. Log any non-empty `warnings[]` and add each to `workflow_warnings[]` as `<field>: <message>`.
|
|
59
54
|
|
|
60
|
-
|
|
61
|
-
- `skill_name` ← `brief.name`
|
|
62
|
-
- `version` ← `brief.version`
|
|
63
|
-
- `source_repo` ← `brief.source_repo`
|
|
64
|
-
- `language` ← `brief.language`
|
|
65
|
-
- `scope_type` ← `brief.scope.type`
|
|
66
|
-
- `forge_tier` ← `brief.forge_tier`
|
|
67
|
-
- `description` ← `brief.description`
|
|
68
|
-
- `created` ← `brief.created`
|
|
69
|
-
- `created_by` ← `brief.created_by`
|
|
70
|
-
- All scope fields: `scope.include`, `scope.exclude`, `scope.notes`, `scope.rationale`, `scope.amendments`, `scope.tier_a_include`
|
|
71
|
-
- Optional fields: `source_type`, `source_authority`, `doc_urls`, `target_version`, `target_ref`, `source_ref`, `scripts_intent`, `assets_intent`
|
|
55
|
+
Nothing the upstream brief carries is rebuilt or dropped: §4's writer starts from the upstream brief file itself. That covers the top-level fields (`name`, `version`, `source_type`, `source_repo`, `language`, `description`, `forge_tier`, `created`, `created_by`, `source_authority`, `doc_urls`, `target_version`, `target_ref`, `source_ref`, `scripts_intent`, `assets_intent`) and all scope fields: `scope.type`, `scope.include`, `scope.exclude`, `scope.notes`, `scope.rationale`, `scope.amendments`, `scope.tier_a_include`, `scope.registry_path`, `scope.ui_variants`, `scope.demo_patterns`. The sections below read `skill_name` ← `brief.name`, `source_repo` ← `brief.source_repo`, `scope_type` ← `brief.scope.type` and `source_type` ← `brief.source_type`.
|
|
72
56
|
|
|
73
|
-
**Docs-only check:** If `source_type` is `docs-only` in the parsed brief, skip §2 (Run Doc Detection) and §3 (Enrich Brief with Detected Docs)
|
|
57
|
+
**Docs-only check:** If `source_type` is `docs-only` in the parsed brief, skip §2 (Run Doc Detection) and §3 (Enrich Brief with Detected Docs): the doc URL is already in the brief's `doc_urls`. Log: "Docs-only brief: skipping repo-based doc detection. Doc URLs provided by upstream." Proceed directly to §4 (Write Enriched Brief). All brief fields (`source_type`, `source_authority`, `doc_urls`, `scope_type`) must pass through unmodified.
|
|
74
58
|
|
|
75
59
|
### 2. Run Doc Detection
|
|
76
60
|
|
|
77
61
|
**Resolve `{detectDocsHelper}`** from `{detectDocsProbeOrder}`; first existing path wins. HALT if no candidate exists.
|
|
78
62
|
|
|
79
|
-
Invoke doc detection to discover documentation URLs for the source repo:
|
|
63
|
+
Invoke doc detection to discover documentation URLs for the source repo, keeping its JSON in the run folder:
|
|
80
64
|
|
|
81
65
|
```bash
|
|
82
|
-
uv run {detectDocsHelper} --repo-url {source_repo}
|
|
66
|
+
uv run {detectDocsHelper} --repo-url "{source_repo}" > "{run_dir}/detected.json"
|
|
83
67
|
```
|
|
84
68
|
|
|
85
|
-
`--repo-url` is always required (the script uses it for GitHub API calls). If a local clone is also available at `{local_clone_path}`, add `--local-path {local_clone_path}` to enable docs-folder scanning in addition to API-based detection.
|
|
69
|
+
`--repo-url` is always required (the script uses it for GitHub API calls). If a local clone is also available at `{local_clone_path}`, add `--local-path "{local_clone_path}"` to enable docs-folder scanning in addition to API-based detection.
|
|
86
70
|
|
|
87
71
|
**Handle exit codes:**
|
|
88
72
|
|
|
89
|
-
- **Exit 0 (found docs):**
|
|
73
|
+
- **Exit 0 (found docs):** Proceed to §3, which reads `{run_dir}/detected.json`.
|
|
90
74
|
- **Exit 1 (none found):** Log: "No external documentation found — brief generated from source analysis only." Proceed to §4 with no doc enrichment.
|
|
91
|
-
- **Exit 2 (error):** Log warning
|
|
75
|
+
- **Exit 2 (error):** Log the warning "Doc detection failed: proceeding without doc enrichment." and add it to `workflow_warnings[]`. Do NOT halt: doc enrichment is best-effort. Proceed to §4 with no doc enrichment.
|
|
92
76
|
|
|
93
77
|
### 3. Enrich Brief with Detected Docs
|
|
94
78
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
- `url` ← `url` (direct copy)
|
|
98
|
-
- `label` ← derive from `content_type` if available:
|
|
99
|
-
- `"api-docs"` → `"API Documentation"`
|
|
100
|
-
- `"guide"` → `"Guide"`
|
|
101
|
-
- `"reference"` → `"Reference"`
|
|
102
|
-
- Otherwise derive from `detected_via`:
|
|
103
|
-
- `"homepageUrl"` → `"Homepage"`
|
|
104
|
-
- `"readme_link"` → `"README Link"`
|
|
105
|
-
- `"pages_api"` → `"GitHub Pages"`
|
|
106
|
-
- `"docs_folder"` → `"Docs Folder"`
|
|
107
|
-
- `source` ← coarse provenance derived from `detected_via` (per the `skill-brief.v1.json` `doc_urls[].source` enum): `homepageUrl` → `homepage`, `readme_link` → `readme-detection`, `pages_api` → `pages-api`, `docs_folder` → `docs-folder`. This marks the entry as opportunistically detected, distinct from a registry-guaranteed corpus.
|
|
108
|
-
|
|
109
|
-
**Merge via the canonical helper.** Resolve `{mergeDocUrlsHelper}` from `{mergeDocUrlsProbeOrder}` (first existing path wins; HALT if neither exists). Pass the upstream brief's `doc_urls` as `existing` and the entries just mapped above as `detected`:
|
|
79
|
+
**Merge via the canonical helper.** Resolve `{mergeDocUrlsHelper}` from `{mergeDocUrlsProbeOrder}` (first existing path wins; HALT if neither exists). It maps each detected entry to the brief's `{url, label, source}`, reads the upstream brief's `doc_urls` itself and merges the two, so no entry is typed here:
|
|
110
80
|
|
|
111
81
|
```bash
|
|
112
|
-
|
|
113
|
-
| uv run {mergeDocUrlsHelper}
|
|
82
|
+
uv run {mergeDocUrlsHelper} --scope-type "{scope_type}" --detected-file "{run_dir}/detected.json" --existing-brief "{brief_path}" > "{run_dir}/doc-urls-merged.json"
|
|
114
83
|
```
|
|
115
84
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
**Log suppressed entries.** When `suppressed` is non-empty, log one line per entry — `"info: suppressed {url} ({reason})"` — so the operator can see what the whole-language noise filter dropped (never drop silently). The N==0 DEGRADED case (a whole-language repo whose registry returned no corpora) carries no `language-registry` entry, so suppression stays inactive and its README docs are kept — this is intentional (there is no canonical corpus host to filter against).
|
|
119
|
-
|
|
120
|
-
### 4. Validate Enriched Brief
|
|
121
|
-
|
|
122
|
-
Assemble the enriched brief context as a flat JSON object following the write-brief §3 contract:
|
|
123
|
-
|
|
124
|
-
```json
|
|
125
|
-
{
|
|
126
|
-
"name": "{skill_name}",
|
|
127
|
-
"target_version": "{target_version or null}",
|
|
128
|
-
"detected_version": null,
|
|
129
|
-
"source_type": "{source_type or 'source'}",
|
|
130
|
-
"source_repo": "{source_repo}",
|
|
131
|
-
"language": "{language}",
|
|
132
|
-
"description": "{description}",
|
|
133
|
-
"forge_tier": "{forge_tier}",
|
|
134
|
-
"created": "{created}",
|
|
135
|
-
"created_by": "{created_by}",
|
|
136
|
-
"scope_type": "{scope_type}",
|
|
137
|
-
"scope_include": ["{scope.include patterns}"],
|
|
138
|
-
"scope_exclude": ["{scope.exclude patterns}"],
|
|
139
|
-
"scope_notes": "{scope.notes or ''}",
|
|
140
|
-
"scope_rationale": null,
|
|
141
|
-
"scope_tier_a_include": null,
|
|
142
|
-
"scope_amendments": null,
|
|
143
|
-
"doc_urls": [{"url": "...", "label": "...", "source": "..."}],
|
|
144
|
-
"scripts_intent": "{scripts_intent or null}",
|
|
145
|
-
"assets_intent": "{assets_intent or null}",
|
|
146
|
-
"source_authority": "{source_authority or null}",
|
|
147
|
-
"target_ref": "{target_ref or null}",
|
|
148
|
-
"source_ref": "{source_ref or null}",
|
|
149
|
-
"version_resolved": "{version}"
|
|
150
|
-
}
|
|
151
|
-
```
|
|
85
|
+
§4 hands the writer that file: its `doc_urls` are the merged list, every upstream entry kept with its `source`. On a non-zero exit, add `Doc merge failed: proceeding without doc enrichment.` to `workflow_warnings[]` and proceed to §4 with no doc enrichment.
|
|
152
86
|
|
|
153
|
-
|
|
87
|
+
**Log suppressed entries.** When its `suppressed` is non-empty, log one line per entry, `"info: suppressed {url} ({reason})"`, so the operator sees each entry the merge dropped and why (never drop silently).
|
|
154
88
|
|
|
155
|
-
###
|
|
89
|
+
### 4. Write Enriched Brief
|
|
156
90
|
|
|
157
91
|
**Resolve `{writeSkillBriefHelper}`** from `{writeSkillBriefProbeOrder}`; first existing path wins. HALT if no candidate exists.
|
|
158
92
|
|
|
159
|
-
Write the enriched brief through the canonical writer:
|
|
93
|
+
Write the enriched brief through the canonical writer. It starts from the upstream brief file (`--base-brief`), keeps every field and the version it holds, replaces `doc_urls` with the merged list (`--doc-urls-file`), validates the result and writes it atomically:
|
|
160
94
|
|
|
161
95
|
```bash
|
|
162
|
-
|
|
96
|
+
uv run {writeSkillBriefHelper} write --target {forge_data_folder}/{skill_name}/skill-brief.yaml --base-brief "{brief_path}" --doc-urls-file "{run_dir}/doc-urls-merged.json"
|
|
163
97
|
```
|
|
164
98
|
|
|
165
|
-
|
|
166
|
-
- Exit 1 (validation/invariant): Emit error envelope per §6 with `halt_reason: "input-invalid"`, then HARD HALT.
|
|
167
|
-
- Exit 2 (I/O failure): Emit error envelope per §6 with `halt_reason: "write-failed"`, then HARD HALT.
|
|
168
|
-
|
|
169
|
-
**On success:** Capture `brief_path` and `version` from the response envelope for step-auto-validate's envelope emission.
|
|
99
|
+
Leave `--doc-urls-file` out when §2 and §3 were skipped or found nothing, or the merge failed.
|
|
170
100
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
**Resolve `{emitBriefEnvelopeHelper}`** from `{emitBriefEnvelopeProbeOrder}`; first existing path wins. HALT if no candidate exists.
|
|
101
|
+
**On script failure (non-zero exit):**
|
|
102
|
+
- Exit 1 of a call with `--doc-urls-file` whose stderr `field` is `doc_urls` (a merged entry the brief schema refuses): doc enrichment is best-effort, so add `Doc enrichment dropped: {its message}` to `workflow_warnings[]`, run the call once more without `--doc-urls-file`, and handle that result.
|
|
103
|
+
- Any other exit 1 (validation/invariant): emit the halt envelope first, `uv run {emitBriefEnvelopeHelper} emit --target stderr` with `halt_reason: "input-invalid"` (SKILL.md Halt Contract), then HARD HALT (exit code 2).
|
|
104
|
+
- Exit 2 (I/O failure): emit the halt envelope first, `uv run {emitBriefEnvelopeHelper} emit --target stderr` with `halt_reason: "write-failed"` (SKILL.md Halt Contract), then HARD HALT (exit code 4).
|
|
176
105
|
|
|
177
|
-
|
|
178
|
-
echo '{"status":"error","skill_name":"{skill_name or unknown}","halt_reason":"{reason}","mode":"auto"}' | \
|
|
179
|
-
uv run {emitBriefEnvelopeHelper} emit --target stderr
|
|
180
|
-
```
|
|
106
|
+
**On success:** Capture `brief_path` and `version` from the response envelope for step-auto-validate's envelope emission, and add each entry of its `warnings[]` to `workflow_warnings[]`.
|
|
181
107
|
|
|
182
|
-
###
|
|
108
|
+
### 5. Chain to Auto-Validate
|
|
183
109
|
|
|
184
|
-
Load, read fully, then execute {nextStepFile}
|
|
110
|
+
Load, read fully, then execute {nextStepFile}, which checks and summarizes the written brief, builds the envelope and runs the hook. Do this only after the enriched brief has been written and validated.
|
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
nextStepFile: 'health-check.md'
|
|
3
|
-
|
|
3
|
+
writeBriefFile: 'write-brief.md'
|
|
4
4
|
validateBriefSchemaProbeOrder:
|
|
5
5
|
- '{project-root}/_bmad/skf/shared/scripts/skf-validate-brief-schema.py'
|
|
6
6
|
- '{project-root}/src/shared/scripts/skf-validate-brief-schema.py'
|
|
7
|
-
writeSkillBriefProbeOrder:
|
|
8
|
-
- '{project-root}/_bmad/skf/shared/scripts/skf-write-skill-brief.py'
|
|
9
|
-
- '{project-root}/src/shared/scripts/skf-write-skill-brief.py'
|
|
10
|
-
emitBriefEnvelopeProbeOrder:
|
|
11
|
-
- '{project-root}/_bmad/skf/shared/scripts/skf-emit-brief-result-envelope.py'
|
|
12
|
-
- '{project-root}/src/shared/scripts/skf-emit-brief-result-envelope.py'
|
|
13
7
|
---
|
|
14
8
|
|
|
15
9
|
<!-- Config: communicate in {communication_language}. -->
|
|
@@ -18,21 +12,20 @@ emitBriefEnvelopeProbeOrder:
|
|
|
18
12
|
|
|
19
13
|
## STEP GOAL:
|
|
20
14
|
|
|
21
|
-
To
|
|
15
|
+
To check the auto-generated brief against the schema and show a concise summary of it, register it in QMD at Deep tier, then build and bind the result envelope (the health check displays it as the run's last line), run the `on_complete` hook and chain to the health check. `[auto]` is a pipeline stage, which the forger always runs headless, so this step asks nothing.
|
|
22
16
|
|
|
23
17
|
## Rules
|
|
24
18
|
|
|
25
19
|
- This step is conditional — only loaded from step-auto-brief.md when `[auto]` mode is active
|
|
26
|
-
- The brief MUST already exist on disk (written by step-auto-brief §
|
|
20
|
+
- The brief MUST already exist on disk (written by step-auto-brief §4) before this step runs
|
|
27
21
|
- Do NOT render YAML or JSON envelopes in the LLM — delegate to deterministic scripts
|
|
28
|
-
- Do NOT modify confirm-brief.md or write-brief.md — the [R]eject path reuses them as-is
|
|
29
22
|
- The 10-line summary is always displayed, even in headless mode, for logging transparency
|
|
30
23
|
|
|
31
24
|
## MANDATORY SEQUENCE
|
|
32
25
|
|
|
33
26
|
### 1. Load Auto-Brief
|
|
34
27
|
|
|
35
|
-
Read the brief from `{forge_data_folder}/{skill_name}/skill-brief.yaml` (written by step-auto-brief §
|
|
28
|
+
Read the brief from `{forge_data_folder}/{skill_name}/skill-brief.yaml` (written by step-auto-brief §4).
|
|
36
29
|
|
|
37
30
|
**Resolve `{validateBriefSchemaHelper}`** from `{validateBriefSchemaProbeOrder}`; first existing path wins. HALT if no candidate exists.
|
|
38
31
|
|
|
@@ -44,11 +37,10 @@ uv run {validateBriefSchemaHelper} {forge_data_folder}/{skill_name}/skill-brief.
|
|
|
44
37
|
|
|
45
38
|
The script returns JSON `{valid, errors[], warnings[], halt_reason, brief}`.
|
|
46
39
|
|
|
47
|
-
- **`valid: false
|
|
48
|
-
- **`valid: true
|
|
40
|
+
- **`valid: false`**: emit the halt envelope first, `uv run {emitBriefEnvelopeHelper} emit --target stderr` with `halt_reason: "input-invalid"` (SKILL.md Halt Contract), then HARD HALT (exit code 2): "**Auto-brief at `{forge_data_folder}/{skill_name}/skill-brief.yaml` is invalid: {first error message}.**"
|
|
41
|
+
- **`valid: true`**: proceed with the parsed `brief` payload. Log any non-empty `warnings[]` and add each to `workflow_warnings[]` as `<field>: <message>`.
|
|
49
42
|
|
|
50
|
-
**IF the file does not exist:**
|
|
51
|
-
- HARD HALT with exit code 2 (`input-missing`): "**Auto-brief not found at `{forge_data_folder}/{skill_name}/skill-brief.yaml` — step-auto-brief must write the brief before this step runs.**" Emit error envelope per §7 with `halt_reason: "input-missing"`.
|
|
43
|
+
**IF the file does not exist:** emit the halt envelope first, `uv run {emitBriefEnvelopeHelper} emit --target stderr` with `halt_reason: "input-missing"` (SKILL.md Halt Contract), then HARD HALT (exit code 2): "**Auto-brief not found at `{forge_data_folder}/{skill_name}/skill-brief.yaml`: step-auto-brief must write the brief before this step runs.**"
|
|
52
44
|
|
|
53
45
|
Extract from the parsed brief:
|
|
54
46
|
- `skill_name` ← `brief.name`
|
|
@@ -81,125 +73,32 @@ Description: "{description}"
|
|
|
81
73
|
|
|
82
74
|
Where `{N}` is the count of `scope_include` patterns and `{M}` is the count of `scope_exclude` patterns. If `doc_urls` is null or empty, display "None detected". The `Pipeline` line names the auto pipeline and the resolved `{forge_tier}` — it carries no numeric quality target, which would be an unverified guarantee an automator might parse as fact.
|
|
83
75
|
|
|
84
|
-
### 3.
|
|
76
|
+
### 3. Envelope, Hook and Chain
|
|
85
77
|
|
|
86
|
-
**
|
|
78
|
+
**QMD registration.** When the run's forge tier (step 1 §1) is Deep, load `{writeBriefFile}` and run its §3b (QMD Collection Registration) alone, with `{skill-name}` ← `{skill_name}`, then come back here: it indexes the brief when QMD is available, and a warning it raises goes on `workflow_warnings[]` before the envelope below is built. Run nothing else of that file. At any other tier, skip this.
|
|
87
79
|
|
|
88
|
-
"
|
|
89
|
-
|
|
90
|
-
Select an action:
|
|
91
|
-
[A] Approve — accept the brief as-is and continue the pipeline
|
|
92
|
-
[E] Edit — modify specific fields before continuing
|
|
93
|
-
[R] Reject — fall back to interactive brief review with pre-populated fields"
|
|
94
|
-
|
|
95
|
-
If `{headless_mode}`: auto-proceed with `[A]pprove`, log: "headless: auto-approve auto-brief".
|
|
96
|
-
|
|
97
|
-
Wait for user response. Branch on the response:
|
|
98
|
-
|
|
99
|
-
- `[A]` or `approve` → §4 ([A]pprove path)
|
|
100
|
-
- `[E]` or `edit` → §5 ([E]dit path)
|
|
101
|
-
- `[R]` or `reject` → §6 ([R]eject path)
|
|
102
|
-
- Any other input → answer briefly, re-display the menu
|
|
103
|
-
|
|
104
|
-
### 4. [A]pprove Path
|
|
105
|
-
|
|
106
|
-
**Resolve `{emitBriefEnvelopeHelper}`** from `{emitBriefEnvelopeProbeOrder}`; first existing path wins. HALT if no candidate exists.
|
|
107
|
-
|
|
108
|
-
Emit the `SKF_BRIEF_RESULT_JSON` envelope with `mode: "auto"`:
|
|
109
|
-
|
|
110
|
-
```bash
|
|
111
|
-
echo '{"status":"success","brief_path":"{brief_path}","skill_name":"{skill_name}","version":"{version}","language":"{language}","scope_type":"{scope_type}","halt_reason":null,"mode":"auto"}' | \
|
|
112
|
-
uv run {emitBriefEnvelopeHelper} emit
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
Where `{brief_path}` is `{forge_data_folder}/{skill_name}/skill-brief.yaml`.
|
|
116
|
-
|
|
117
|
-
Chain to {nextStepFile} (health-check.md) — load, read fully, then execute.
|
|
118
|
-
|
|
119
|
-
### 5. [E]dit Path
|
|
120
|
-
|
|
121
|
-
Present each brief field with its current value and accept natural language modification requests.
|
|
122
|
-
|
|
123
|
-
"**Editable fields:**
|
|
124
|
-
|
|
125
|
-
1. **Name:** {skill_name}
|
|
126
|
-
2. **Source:** {source_repo}
|
|
127
|
-
3. **Language:** {language}
|
|
128
|
-
4. **Scope type:** {scope_type}
|
|
129
|
-
5. **Include patterns:** {scope_include}
|
|
130
|
-
6. **Exclude patterns:** {scope_exclude}
|
|
131
|
-
7. **Description:** {description}
|
|
132
|
-
8. **Doc URLs:** {doc_urls or "None"}
|
|
133
|
-
9. **Version:** {version}
|
|
134
|
-
10. **Forge tier:** {forge_tier}
|
|
135
|
-
|
|
136
|
-
Tell me what to change (e.g. 'change scope type to public-api', 'add doc URL https://...')."
|
|
137
|
-
|
|
138
|
-
Wait for user response. Apply changes to the brief context.
|
|
139
|
-
|
|
140
|
-
**Re-write the modified brief** through the canonical writer:
|
|
141
|
-
|
|
142
|
-
**Resolve `{writeSkillBriefHelper}`** from `{writeSkillBriefProbeOrder}`; first existing path wins.
|
|
143
|
-
|
|
144
|
-
Assemble the modified brief context as a flat JSON object (same format as step-auto-brief §4):
|
|
80
|
+
Build the `SKF_BRIEF_RESULT_JSON` envelope with `mode: "auto"`, through the `{emitBriefEnvelopeHelper}` SKILL.md On Activation step 4 resolved (`references/invocation-contract.md` defines each field). Bind `{result_envelope_line}` to the line it prints, and do not display it here: the shared health check displays it verbatim as the run's last line, the final message the pipeline reads:
|
|
145
81
|
|
|
146
82
|
```bash
|
|
147
|
-
|
|
83
|
+
uv run {emitBriefEnvelopeHelper} emit <<'SKF_BRIEF_RESULT'
|
|
84
|
+
{"status":"success","brief_path":"{brief_path}","skill_name":"{skill_name}","version":"{version}","language":"{language}","scope_type":"{scope_type}","halt_reason":null,"mode":"auto","warnings":[<workflow_warnings[] as JSON strings>]}
|
|
85
|
+
SKF_BRIEF_RESULT
|
|
148
86
|
```
|
|
149
87
|
|
|
150
|
-
|
|
88
|
+
Where `{brief_path}` is `{forge_data_folder}/{skill_name}/skill-brief.yaml`. If `{emitBriefEnvelopeHelper}` has no path, or the helper exits non-zero or prints no line, leave `{result_envelope_line}` empty and display its error: the brief is already written, so the run goes on.
|
|
151
89
|
|
|
152
|
-
**
|
|
153
|
-
|
|
154
|
-
**Resolve `{validateBriefSchemaHelper}`** from `{validateBriefSchemaProbeOrder}`; first existing path wins.
|
|
90
|
+
**On-complete hook.** Right after the envelope, if `{onCompleteCommand}` is non-empty (resolved at SKILL.md On Activation §3 from `workflow.on_complete`), run it:
|
|
155
91
|
|
|
156
92
|
```bash
|
|
157
|
-
|
|
93
|
+
{onCompleteCommand} --result-path={brief_path}
|
|
158
94
|
```
|
|
159
95
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
Re-present the 10-line summary (§2 format) with updated values so the user can verify the change.
|
|
163
|
-
|
|
164
|
-
"Updated brief written. **Select:** [A] Approve and continue · [E] Edit more · [R] Reject"
|
|
165
|
-
|
|
166
|
-
- `[A]` → emit envelope per §4, chain to {nextStepFile}
|
|
167
|
-
- `[E]` → repeat §5 edit loop
|
|
168
|
-
- `[R]` → §6 ([R]eject path)
|
|
169
|
-
|
|
170
|
-
### 6. [R]eject Path
|
|
96
|
+
A hook error never fails the run: on a non-zero exit or a process error, display one line, `on_complete hook failed (exit {code}): {first line of its stderr}`, and continue. The envelope is already bound, so it does not carry this line. When `{onCompleteCommand}` is empty, skip the hook.
|
|
171
97
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
Hydrate brief context variables from the auto-brief on disk, using the same field mapping as the ratify path in gather-intent §3.1a:
|
|
175
|
-
|
|
176
|
-
- `name` ← `brief.name`; `version` ← `brief.version`; `target_version` ← `brief.target_version`
|
|
177
|
-
- `target_ref` ← `brief.target_ref`; `source_ref` ← `brief.source_ref` (optional git refs; preserve when present)
|
|
178
|
-
- `source_repo` ← `brief.source_repo`; `source_type` ← `brief.source_type`; `source_authority` ← `brief.source_authority`; `doc_urls` ← `brief.doc_urls`
|
|
179
|
-
- `language` ← `brief.language`; `description` ← `brief.description`; `forge_tier` ← `brief.forge_tier`
|
|
180
|
-
- `created` ← `brief.created`; `created_by` ← `brief.created_by`
|
|
181
|
-
- `scope.type` / `scope.include` / `scope.exclude` / `scope.tier_a_include` / `scope.notes` / `scope.rationale` / `scope.amendments` ← `brief.scope.*` (preserve `tier_a_include` and the `amendments` log verbatim — do not re-derive or drop them)
|
|
182
|
-
- `scripts_intent` ← `brief.scripts_intent`; `assets_intent` ← `brief.assets_intent`
|
|
183
|
-
|
|
184
|
-
Set `ratify_mode: true` and `ratify_source_path: {forge_data_folder}/{skill_name}/skill-brief.yaml` in workflow context.
|
|
185
|
-
|
|
186
|
-
Chain to {rejectTargetFile} (confirm-brief.md) — load, read fully, then execute. The user gets the full interactive review experience: view, adjust fields inline, revise scope via [R], or approve via [C] → write-brief.md → health-check.md.
|
|
187
|
-
|
|
188
|
-
The interactive chain's write-brief.md handles its own envelope emission with `mode: null` (interactive), which is correct since the user explicitly chose to leave auto mode.
|
|
189
|
-
|
|
190
|
-
### 7. Error Envelope (Canonical)
|
|
191
|
-
|
|
192
|
-
Every HARD HALT in this step emits the error envelope on stderr:
|
|
193
|
-
|
|
194
|
-
**Resolve `{emitBriefEnvelopeHelper}`** from `{emitBriefEnvelopeProbeOrder}`; first existing path wins.
|
|
98
|
+
**Remove the run folder.** The brief is written, so the folder step 1 §1 created has done its job; remove it (the guard keeps the command to that folder):
|
|
195
99
|
|
|
196
100
|
```bash
|
|
197
|
-
|
|
198
|
-
uv run {emitBriefEnvelopeHelper} emit --target stderr
|
|
101
|
+
case "{run_dir}" in "{project-root}/_bmad-output/.skf-run/skf-brief-skill-"*) rm -rf "{run_dir}" ;; esac
|
|
199
102
|
```
|
|
200
103
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
Load, read fully, then execute the appropriate next step file — only after the user has made their choice and the corresponding action has been taken (envelope emitted or context hydrated):
|
|
204
|
-
- [A]pprove or [E]dit (after final approve): {nextStepFile} (health-check.md)
|
|
205
|
-
- [R]eject: {rejectTargetFile} (confirm-brief.md)
|
|
104
|
+
Chain to {nextStepFile} (health-check.md): load, read fully, then execute. The health check only relays to the shared check: the envelope and the hook of this path run here.
|
|
@@ -1,19 +1,15 @@
|
|
|
1
1
|
# Version Resolution
|
|
2
2
|
|
|
3
|
-
Single source of truth for how brief-skill resolves the `version` field of `skill-brief.yaml`. Loaded by step 2 §4b (auto-detect,
|
|
4
|
-
|
|
5
|
-
**Aligned with** `assets/skill-brief-schema.md` "Version Detection" section. If you change one, change the other.
|
|
3
|
+
Single source of truth for how brief-skill resolves the `version` field of `skill-brief.yaml`. Loaded by step 2 §4b (auto-detect, when §4.2's fallback read the source) and step 5 §3 (resolve & write) so both operate on the same precedence rules and invariant. Step-01 §3b references this file in prose for human-readable rationale but does not load it: that step only collects `target_version` and checks its shape with `skf-validate-brief-inputs.py --only target_version`.
|
|
6
4
|
|
|
7
5
|
## Detection Algorithm
|
|
8
6
|
|
|
9
|
-
|
|
7
|
+
Step 2 §4.1's extractor detects the version of the languages it reads, with `--resolve-version`: the manifest's literal version, then a version file or a Cargo workspace root, then the release tag (`skf-extract-public-api.py --help` gives the order). When §4.2 read the source instead, attempt these lookups in order and stop at the first match:
|
|
10
8
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
- **Rust:** `Cargo.toml` `[package] version` (static). If `version = { workspace = true }`, resolve from workspace root `Cargo.toml` → `git describe --tags --abbrev=0`.
|
|
14
|
-
- **Go:** version tag from `go.mod`, or `git describe --tags --abbrev=0`.
|
|
9
|
+
1. The version the manifest or a version file writes as a literal: `package.json`'s `"version"`, `pyproject.toml`'s `[project] version` or a package's `__version__`, a `.gemspec` or `version.rb` `VERSION`, a `.csproj` `<Version>`, `composer.json`'s `"version"`.
|
|
10
|
+
2. The tag lookup. For a GitHub source, `uv run {githubProbeHelper} tags --repo "{owner}/{repo}" --ref "{analysis_ref}" --limit 1`: its `release.version` is the version (the newest release tag at `HEAD`, the pinned tag itself at a tag, none at a branch or a commit), and a null `release` or a non-zero exit gives none. For a local source, `git -C "{source_path}" describe --tags --abbrev=0`: a tag whose name is a version gives it, a leading `v` dropped.
|
|
15
11
|
|
|
16
|
-
For remote GitHub sources,
|
|
12
|
+
For remote GitHub sources, read version-bearing files from `{run_dir}/files/`, where step 2 stages the files it fetches; fetch one that is not there yet with step 2's fetch helper, naming it: `uv run {githubFetchHelper} --repo "{owner}/{repo}" --ref "{analysis_ref}" --tree-file "{run_dir}/tree.json" --dest "{run_dir}/files" "{file}"`. `{analysis_ref}` is the ref resolved in step 02 §1, defaulting to `HEAD` when no `target_ref`/`target_version` was pinned; reading at the pinned ref keeps the "Detected version" consistent with the version being skilled. For local sources, read the file directly.
|
|
17
13
|
|
|
18
14
|
If every step fails or returns a non-semver value, the detected version is `null` — the resolver below falls back to `"1.0.0"`.
|
|
19
15
|
|
|
@@ -42,5 +38,6 @@ Step-05 §3 enforces this by setting both fields to the same string when `target
|
|
|
42
38
|
| Step | Responsibility |
|
|
43
39
|
|------|----------------|
|
|
44
40
|
| 01 §3b | Collect `target_version` (interactive prompt, or headless arg). Do not auto-detect — that is step 02's job. |
|
|
45
|
-
| 02 §
|
|
41
|
+
| 02 §1 | Resolve `target_version` to the git tag step 2 reads, through `skf-validate-pins.py`. With no match, analyze `HEAD` and warn. |
|
|
42
|
+
| 02 §4b | Detect the version (§4.1's extractor, or the detection algorithm after §4.2) regardless of whether `target_version` is set. If `target_version` is set and the detected version differs, surface the disagreement to the user; the precedence above is unchanged, so `target_version` wins. |
|
|
46
43
|
| 05 §3 | Apply the precedence rules and write `version`. If `target_version` is set, also write the `target_version` field with the identical value. Enforce the invariant. |
|