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
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
nextStepFile: 'step-05-skill-loop.md'
|
|
3
3
|
stateSchemaFile: 'assets/campaign-state-schema.json'
|
|
4
4
|
stateFile: '{campaignWorkspacePath}/_campaign-state.yaml'
|
|
5
|
-
backupFile: '{campaignWorkspacePath}/_campaign-state.yaml.bak'
|
|
6
5
|
briefFile: '{campaignWorkspacePath}/campaign-brief.yaml'
|
|
6
|
+
provenanceResultsFile: '{campaignWorkspacePath}/_provenance-results.json'
|
|
7
|
+
decisionLogFile: '{campaignWorkspacePath}/_campaign-decision-log.md'
|
|
7
8
|
provenanceScript: 'scripts/campaign-provenance.py'
|
|
9
|
+
stateScript: 'scripts/campaign-state.py'
|
|
8
10
|
validateScript: 'scripts/campaign-validate-state.py'
|
|
9
11
|
---
|
|
10
12
|
|
|
@@ -18,46 +20,45 @@ Verify that all target repositories are accessible and record the exact commit S
|
|
|
18
20
|
|
|
19
21
|
## RULES
|
|
20
22
|
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
- Any inaccessible repo halts the campaign
|
|
24
|
-
-
|
|
25
|
-
- Update `campaign.current_stage` to `3`.
|
|
26
|
-
- Update `campaign.last_updated` to current ISO-8601 with timezone on every write.
|
|
27
|
-
- If `{headless_mode}` is true, auto-proceed through confirmation gates with the default action and log each auto-decision.
|
|
23
|
+
- Write `campaign.current_stage` = 3 only in this stage's final state write, after every gate: step-resume resumes at `current_stage + 1`, so an early write skips unfinished work.
|
|
24
|
+
- Write state and decision-log entries only through `{stateScript}`, and on a non-zero exit HALT with the same code (State Contract in `references/campaign-contracts.md`). A log entry is `uv run {stateScript} log --log-file {decisionLogFile} --type <decision|auto|event> --text '<entry>'`.
|
|
25
|
+
- Any inaccessible repo halts the campaign: all targets must be reachable before skill processing begins. The brief holds each `repo_url` (the state schema has no place for it).
|
|
26
|
+
- If `{headless_mode}` is true, emit this stage's progress events, and at any HARD HALT the error envelope, per `references/campaign-contracts.md`.
|
|
28
27
|
|
|
29
28
|
## TASKS
|
|
30
29
|
|
|
31
|
-
### §1
|
|
30
|
+
### §1: Read + Validate State
|
|
32
31
|
|
|
33
32
|
Load `{stateFile}`. Run `uv run {validateScript} --state-file {stateFile}`; on non-zero, HALT (exit 3) with the script's `errors[]`.
|
|
34
33
|
|
|
35
|
-
### §2
|
|
34
|
+
### §2: Read Brief
|
|
36
35
|
|
|
37
36
|
Load `{briefFile}` only to confirm it parses (the provenance script reads it directly). HALT (exit code 8, `missing-brief`) if the brief is missing or unreadable.
|
|
38
37
|
|
|
39
|
-
### §3
|
|
38
|
+
### §3: Verify Repo Access + Record Commit SHAs
|
|
40
39
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
### §4 — Verify Repo Access + Record Commit SHAs
|
|
44
|
-
|
|
45
|
-
Run the deterministic provenance check — do not parse repo URLs or shell out to `gh` by hand:
|
|
40
|
+
Run the deterministic provenance check, keeping its JSON output in `{provenanceResultsFile}` for §5; do not parse repo URLs or call `gh` by hand:
|
|
46
41
|
|
|
47
42
|
```
|
|
48
|
-
uv run {provenanceScript} --state-file {stateFile} --brief-file {briefFile}
|
|
43
|
+
uv run {provenanceScript} --state-file {stateFile} --brief-file {briefFile} > {provenanceResultsFile}
|
|
49
44
|
```
|
|
50
45
|
|
|
51
|
-
|
|
46
|
+
It writes `results[]`, one per skill with its `commit_sha` (of the skill's `pin`, else the default branch), `status`, `error` and `error_class` (`unauthenticated`, `not-found`, `rate-limited`, `forbidden`, `network`, or `other` for a target it could not look up), plus `all_accessible`, `inaccessible_count` and `systemic_hint`. Exit 0 = all accessible, 1 = one or more inaccessible, 2 = error (missing files, bad YAML, `gh` not installed, or `INVALID_BRIEF`: a brief that is no mapping or holds a target with no `name` or no `repo_url`). On script exit 2, HALT (exit code 2, `invalid-input`) surfacing the error; only when `gh` is what is missing, add that repo access cannot be verified without it.
|
|
47
|
+
|
|
48
|
+
### §4: Handle Inaccessible Repos
|
|
52
49
|
|
|
53
|
-
|
|
50
|
+
If `all_accessible` is `false` (script exit 1), HALT (exit code 6, `inaccessible-repo`) and list each inaccessible repo with its URL, its `error_class` and its `error`. When the script returns a non-null `systemic_hint` (every target failed the same way: unauthenticated `gh`, no network, a rate limit, an organization's SSO policy), show that root-cause line first, above the per-repo errors, never in their place. Do NOT partially proceed: all repos must be verified before writing state.
|
|
54
51
|
|
|
55
|
-
|
|
52
|
+
### §5: Write State
|
|
56
53
|
|
|
57
|
-
|
|
54
|
+
Write every commit SHA and the stage in one write:
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
uv run {stateScript} apply-provenance --state-file {stateFile} --results-file {provenanceResultsFile} --stage 3
|
|
58
|
+
```
|
|
58
59
|
|
|
59
|
-
|
|
60
|
+
It sets each skill's `commit_sha` from `results[]` and refuses results that hold an inaccessible repo (exit 6, nothing written: HALT as in §4); on exit 3, HALT (exit code 3, `invalid-state`).
|
|
60
61
|
|
|
61
62
|
## OUTPUT
|
|
62
63
|
|
|
63
|
-
Display provenance summary
|
|
64
|
+
Display provenance summary: for each target, show name, repo URL, and recorded commit SHA. Chain to `{nextStepFile}`.
|
|
@@ -2,11 +2,15 @@
|
|
|
2
2
|
nextStepFile: 'step-06-batch.md'
|
|
3
3
|
stateSchemaFile: 'assets/campaign-state-schema.json'
|
|
4
4
|
stateFile: '{campaignWorkspacePath}/_campaign-state.yaml'
|
|
5
|
-
backupFile: '{campaignWorkspacePath}/_campaign-state.yaml.bak'
|
|
6
5
|
briefFile: '{campaignWorkspacePath}/campaign-brief.yaml'
|
|
6
|
+
decisionLogFile: '{campaignWorkspacePath}/_campaign-decision-log.md'
|
|
7
|
+
preapplyLogFile: '{campaignWorkspacePath}/preapply-log.json'
|
|
8
|
+
factsFile: '{campaignWorkspacePath}/_facts.json'
|
|
7
9
|
depsScript: 'scripts/campaign-deps.py'
|
|
8
10
|
kickoffTemplate: '{kickoffTemplatePath}'
|
|
9
11
|
kickoffScript: 'scripts/campaign-render-kickoff.py'
|
|
12
|
+
gateScript: 'scripts/campaign-quality-gate.py'
|
|
13
|
+
stateScript: 'scripts/campaign-state.py'
|
|
10
14
|
validateScript: 'scripts/campaign-validate-state.py'
|
|
11
15
|
---
|
|
12
16
|
|
|
@@ -20,85 +24,100 @@ Iterate skills in `dependency_graph.execution_order`, processing each Tier A ski
|
|
|
20
24
|
|
|
21
25
|
## RULES
|
|
22
26
|
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
- The per-skill pipeline body (§5.2) runs inline, not in a delegated subagent: AN→BS→CS→TS are nested skill activations, and a subagent cannot spawn further subagents — running inline keeps the full pipeline reachable and writes each skill's state before the next begins.
|
|
29
|
-
- If `{headless_mode}` is true, auto-proceed through confirmation gates. Dependency gate blocks default to HALT (safest — never silently skip dependencies).
|
|
27
|
+
- Write `campaign.current_stage` = 4 only in this stage's final state write (§6), after every skill: step-resume resumes at `current_stage + 1`, so an early write skips unfinished work. An interrupted skill needs no stage write: it stays `active`, and resume sends an active Tier A skill back to this stage.
|
|
28
|
+
- Write state and decision-log entries only through `{stateScript}`, and on a non-zero exit HALT with the same code (State Contract in `references/campaign-contracts.md`). A log entry is `uv run {stateScript} log --log-file {decisionLogFile} --type <decision|auto|event> --text '<entry>'`.
|
|
29
|
+
- Write state after EACH skill completes (not just at end): context death between skills must be survivable.
|
|
30
|
+
- The per-skill pipeline body (§5.2) runs inline, not in a delegated subagent: BS→CS→TS are nested skill activations, and a subagent cannot spawn further subagents, so running inline keeps the full pipeline reachable and writes each skill's state before the next begins.
|
|
31
|
+
- If `{headless_mode}` is true, auto-proceed through confirmation gates; at a blocked skill, headless takes §4.6's `default_action` and never forces a dependency. Emit this stage's progress events, and at any HARD HALT the error envelope, per `references/campaign-contracts.md`.
|
|
30
32
|
|
|
31
33
|
## TASKS
|
|
32
34
|
|
|
33
|
-
### §1
|
|
35
|
+
### §1: Read + Validate State
|
|
34
36
|
|
|
35
37
|
Load `{stateFile}`. Run `uv run {validateScript} --state-file {stateFile}`; on non-zero, HALT (exit 3) with the script's `errors[]`.
|
|
36
38
|
|
|
37
|
-
### §2
|
|
39
|
+
### §2: Read Brief
|
|
38
40
|
|
|
39
|
-
Load `{briefFile}
|
|
41
|
+
Load `{briefFile}` only to confirm it parses (the kickoff script reads it directly). HALT (exit code 8, `missing-brief`) if the brief is missing or unreadable.
|
|
40
42
|
|
|
41
|
-
### §3
|
|
43
|
+
### §3: Read Directive
|
|
42
44
|
|
|
43
|
-
If `campaign.directive_path` is set in state,
|
|
45
|
+
If `campaign.directive_path` is set in state, the directive steers this stage through two scripts, so apply none of it by hand: the gate script's resolve calls read its `## Skip List` and `## Quality Overrides` for each skill (§4 and §5, re-reading the file, so an edit between skills takes effect), and the kickoff script inlines the whole file into each kickoff (§5), where its other sections are the campaign-wide context the directive contract in `references/campaign-directive-spec.md` describes. If the file is not found, continue without error (directive is optional).
|
|
44
46
|
|
|
45
|
-
### §4
|
|
47
|
+
### §4: Dependency Gate Check
|
|
46
48
|
|
|
47
49
|
For each skill in `dependency_graph.execution_order`, before processing:
|
|
48
50
|
|
|
49
|
-
1. Skip Tier B skills
|
|
51
|
+
1. Skip Tier B skills: they are processed in step-06 via batch mode.
|
|
50
52
|
2. Skip skills whose status is already `"completed"`, `"failed"`, or `"skipped"` (resume support).
|
|
51
|
-
3.
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
53
|
+
3. Resolve the skill's run, passing `--directive-file` when state sets `campaign.directive_path`:
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
uv run {gateScript} resolve --state-file {stateFile} --skill {skill_name} --brief-file {briefFile} [--directive-file <campaign.directive_path>]
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
When `skip` is true, the directive's Skip List names the skill: mark it skipped (`uv run {stateScript} set-skill --state-file {stateFile} --skill {skill_name} --status skipped`), log "directive Skip List: {skill_name} ({skip_reason})" (type `event`), and continue to the next skill. Otherwise keep its `brief_skill`, the brief-skill inputs §5.2 copies. Its `unparsed` entries and `warnings` lines describe the directive, not the skill: log them to the decision log once per stage, from the first resolve call, and again only when a later call reports different ones. On exit 2, HALT with its `error`: exit code 8 (`missing-brief`) when its `code` is `BRIEF_NOT_FOUND`, `BRIEF_UNREADABLE` or `TARGET_NOT_FOUND` (the brief has no target for the skill), else exit code 2 (`invalid-input`): an override that breaks the gate, or a directive that cannot be read.
|
|
60
|
+
4. Run `uv run {depsScript} --check --state-file {stateFile} --skill {skill_name}`.
|
|
61
|
+
5. If `ready: true`, proceed to §5 for this skill.
|
|
62
|
+
6. If `ready: false`, present the blocked skill and each unmet dependency with its status (`unmet_status`):
|
|
63
|
+
- `[S]kip`: mark the skill skipped with the `set-skill --status skipped` call above, log it, continue to the next skill.
|
|
64
|
+
- `[F]orce`: re-run with `--force`, proceed to §5 despite unmet deps.
|
|
65
|
+
- `[H]alt`: stop the campaign with exit code 13 (`dependency-blocked`); state is intact and resumable.
|
|
66
|
+
|
|
67
|
+
**GATE [default: `default_action`]**: headless, take `default_action`. `skip` (every unmet dependency failed or was skipped, so none can complete in this run) runs `[S]kip` and logs "headless: skipped {skill_name}: {dependency} is {status}" for each unmet dependency, so the independent skills after it still run. `halt` (a dependency is still pending or active, an order the loop cannot follow) runs `[H]alt`. In execution order every dependency comes first, so `halt` is defensive: only a `--from` resume or a hand-edited state leaves a dependency pending.
|
|
68
|
+
7. **Deadlock detection** (defensive: Strategy rejects every order the loop cannot follow and §4.6 settles each blocked skill as the loop reaches it, so only a hand-edited state gets here): after iterating through all remaining skills and finding none ready, present the same recovery menu as §4.6, scoped to the mutually-blocked set (this is the strictly harder situation, so it must not get worse UX than a single blocked skill):
|
|
58
69
|
- List the blocked skills and their unmet dependencies.
|
|
59
|
-
- `[F]orce one
|
|
60
|
-
- `[S]kip one
|
|
61
|
-
- `[H]alt
|
|
70
|
+
- `[F]orce one`: choose a skill to re-run with `--force` and resume the loop from it.
|
|
71
|
+
- `[S]kip one`: choose a skill to mark skipped (`set-skill --status skipped`), then re-evaluate readiness.
|
|
72
|
+
- `[H]alt`: stop the campaign loop with exit code 7 (`dependency-deadlock`).
|
|
62
73
|
|
|
63
|
-
|
|
74
|
+
**GATE [default: HALT]**: headless takes `[H]alt` (exit code 7, `dependency-deadlock`) and never forces a dependency. Log the chosen action to the decision log.
|
|
75
|
+
|
|
76
|
+
### §5: Per-Skill Processing
|
|
64
77
|
|
|
65
78
|
For each ready Tier A skill:
|
|
66
79
|
|
|
67
|
-
1. **Activate
|
|
80
|
+
1. **Activate:** `uv run {stateScript} set-skill --state-file {stateFile} --skill {skill_name} --status active`. It stamps `started_at` from the clock, or keeps the start of a run an interruption left `active`.
|
|
68
81
|
2. **Execute pipeline:**
|
|
69
|
-
- **Pre-apply
|
|
82
|
+
- **Pre-apply:** apply known workarounds before generation by running the shared pre-apply helper against the skill's working directory:
|
|
70
83
|
```
|
|
71
84
|
uv run {project-root}/_bmad/skf/shared/scripts/skf-preapply.py --target-dir <skill-working-dir> --log-dir {campaignWorkspacePath}
|
|
72
85
|
```
|
|
73
|
-
(During development the helper lives at `src/shared/scripts/skf-preapply.py`.)
|
|
74
|
-
- **Kickoff emit
|
|
86
|
+
(During development, with no `{project-root}/_bmad/skf/shared/scripts/skf-preapply.py` installed, the helper lives at `{project-root}/src/shared/scripts/skf-preapply.py`.) It writes its `applied[]` workarounds to `{preapplyLogFile}`, which the kickoff script reads. Pre-apply is best-effort: if the helper is missing or exits non-zero, log a warning and proceed (it is not a gate), and leave `--workarounds-file` out of the kickoff call below, so an earlier skill's log is never listed for this one.
|
|
87
|
+
- **Kickoff emit:** render the whole kickoff message with the kickoff script, which fills every placeholder of the template. The customization resolver pipes the persistent facts into it:
|
|
75
88
|
```
|
|
76
|
-
uv run {kickoffScript} --state-file {stateFile} --brief-file {briefFile} --skill {skill_name} --template {kickoffTemplate} --workarounds
|
|
89
|
+
uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --project-root {project-root} --key workflow.persistent_facts | uv run {kickoffScript} --state-file {stateFile} --brief-file {briefFile} --skill {skill_name} --template {kickoffTemplate} [--workarounds-file {preapplyLogFile}] --facts-json - --project-root {project-root} [--directive-file <campaign.directive_path>]
|
|
77
90
|
```
|
|
78
|
-
|
|
79
|
-
- `
|
|
80
|
-
-
|
|
81
|
-
|
|
82
|
-
Present the
|
|
83
|
-
- **
|
|
84
|
-
|
|
91
|
+
- `--facts-json -` takes `workflow.persistent_facts` from the resolver unchanged. When the resolver is missing or fails, write the `persistent_facts` list of `{skill-root}/customize.toml`, as written, to `{factsFile}` as a JSON list with your file-writing tool, and replace the pipe with `< {factsFile}`: no fact or workaround ever passes through shell quoting.
|
|
92
|
+
- `--workarounds-file` is passed when pre-apply exited 0 for this skill; the script lists each workaround it applied (the file, the fingerprint and its fix, the severity).
|
|
93
|
+
- `--directive-file` is passed when state sets `campaign.directive_path`.
|
|
94
|
+
|
|
95
|
+
Present the script's output unchanged as the context for the skill's pipeline run, and fill nothing in by hand. An exit 2 with no JSON on stderr is a usage error from a mangled call, not invalid input: fix the call and run it again. An exit 2 with JSON names its `code`: on `BAD_WORKAROUNDS` or `BAD_FACTS` this call's input is wrong, so correct it and run the call again; on `BRIEF_NOT_FOUND` or `BRIEF_UNREADABLE`, HALT (exit code 8, `missing-brief`); on any other code, HALT (exit code 2, `invalid-input`) with its `error`. Correct a call once only: when the corrected call fails too, HALT (exit code 2, `invalid-input`).
|
|
96
|
+
- **BS → CS → TS**: the forge pipeline for a named skill, the chain the forger's `forge` alias runs. Run each sub-skill with `--headless`, so no nested gate waits and each prints its result envelope. A sub-skill that fails ends the pipeline, and the skill fails (§5.3) with its `halt_reason`. Campaign runs no analyze-source pass: brief-skill scopes the named skill itself, while analyze-source names its briefs from the repository, so brief-skill would overwrite or never read them.
|
|
97
|
+
- **BS** (`skf-brief-skill`): `--headless --force` with each non-null field of §4's `brief_skill` as the input of that name (`target_repo`, `skill_name`, `target_version`, `language_hint`, `scope_hint`); copy them, never read them out of the kickoff. `target_version` is the skill's pin: Setup accepts only an X.Y.Z version as a Tier A pin, and brief-skill refuses any other shape with `input-invalid`, so a pin never silently drops out of the build. `--force` replaces a brief an earlier attempt wrote under this name. Record the `brief_path` of its SKF_BRIEF_RESULT_JSON at once, so resume and the report have it: `uv run {stateScript} set-skill --state-file {stateFile} --skill {skill_name} --brief-path <brief_path>`. An envelope with `status` `error`, or none, fails the skill.
|
|
98
|
+
- **CS** (`skf-create-skill`): `--headless` with that `brief_path`. CS prints an SKF_CREATE_SKILL_RESULT_JSON line (on stderr) only when it halts; that line fails the skill with its `summary.halt_reason`. On success, keep the `{skill_package}` its report names (the compiled skill's folder): §5.3 records it.
|
|
99
|
+
- **TS** (`skf-test-skill`): first resolve the gate again, right before the test, so a directive edit made during this skill counts and the threshold never has to survive the nested runs in conversation context: `uv run {gateScript} resolve --state-file {stateFile} --skill {skill_name} [--directive-file <campaign.directive_path>]` (exit 2 HALTs as at §4). Then run `{skill_name} --headless --threshold={threshold}` with that call's `threshold`, and `pipeline_alias` set to `campaign` in its data context (the explicit threshold wins over test-skill's per-pipeline default). TS settles its verdict, caps and 80% floor fallback itself; §5.3 reads the result.
|
|
100
|
+
- **Doc-rot check:** **record** what CS step 5c already produced; do not re-derive it. Because the pipeline body runs inline (see the RULES note on inline execution), that step's context is directly readable here. Its `correction_matches` holds only the corrections step 5c's judgment pass kept and wrote as `## CORRECTION` blocks, each with `source`, `pattern`, `candidate_category`, `context_line` and `affected`; the candidates the pass rejected are not corrections, so they are never recorded. Append one entry per `correction_matches` record to the skill's `workarounds_applied` array, written as `[doc-rot] {affected}: {candidate_category}`, so they survive in state: `uv run {stateScript} append-workarounds --state-file {stateFile} --skill {skill_name} --entry '<entry>'`, one single-quoted `--entry` per record (an entry the skill already holds is not added twice, so a resumed skill records each correction once). When step 5c took its skip branch (`doc_rot_triggered: false`, `corrections_added: 0`), there is nothing to record: append nothing and move on.
|
|
85
101
|
|
|
86
102
|
**Do not hand-grep the feeder artifacts here, and do not re-run the scan.** `skf-create-skill/references/step-doc-rot.md` §2 requires the scan to run in its helper precisely so identical feeders yield identical matches; a second pass in this loop is free to disagree with the corrections CS actually wrote. It would also be self-contaminating: step 5c has already written `## CORRECTION` blocks into the compiled SKILL.md, and the helper's exclusion windows cover only that file's frontmatter and its Migration & Deprecation Warnings section — so re-scanning it would re-match the blocks 5c itself authored and record them as fresh findings.
|
|
87
|
-
3. **Record results:**
|
|
88
|
-
- On success: set `status` to `"completed"`, set `completed_at` to current ISO-8601 with timezone, record `quality_score`. Backup and write state.
|
|
89
|
-
- On failure: set `status` to `"failed"`. Log the failure reason (the sub-skill's `halt_reason`/exit code, or "unparseable result envelope") to the decision log so `campaign status` and the report surface *why* a skill failed without the operator opening sub-skill logs. Backup and write state. Downstream skills whose `depends_on` does NOT include the failed skill continue processing normally; those that DO depend on it are blocked at §4's dependency gate.
|
|
103
|
+
3. **Record results:** settle the skill from its test verdict, never from an envelope's `status` (TS reports `success` for a scored FAIL too). Pipe the SKF_TEST_RESULT_JSON line TS printed (on stdout for a scored run, on stderr when it halted) to the gate script, and nothing when it printed none:
|
|
90
104
|
|
|
91
|
-
|
|
105
|
+
```
|
|
106
|
+
uv run {gateScript} record --skill {skill_name} <<'SKF_RESULT'
|
|
107
|
+
<the SKF_TEST_RESULT_JSON line TS printed>
|
|
108
|
+
SKF_RESULT
|
|
109
|
+
```
|
|
92
110
|
|
|
93
|
-
|
|
111
|
+
- `status` `completed` (verdict PASS, a threshold-fallback PASS included): `uv run {stateScript} set-skill --state-file {stateFile} --skill {skill_name} --status completed --quality-score <quality_score> --skill-path <skill_package>`, with its `quality_score` and the `{skill_package}` CS named; the helper stamps `completed_at`. Whether the skill exports is decided at Export (step-10), against its gate.
|
|
112
|
+
- `status` `failed` (FAIL, INCONCLUSIVE, pass-with-drift, an error envelope or no readable result), or an earlier sub-skill failed: `uv run {stateScript} set-skill --state-file {stateFile} --skill {skill_name} --status failed [--quality-score <quality_score>]`, with `--quality-score` when it has one. Log the failure reason as an `event` (the record's `reason`, the failing sub-skill's `halt_reason`/exit code, or "unparseable result envelope") to the decision log so `campaign status` and the report surface *why* a skill failed without the operator opening sub-skill logs. Downstream skills whose `depends_on` does NOT include the failed skill continue processing normally; those that DO depend on it are blocked at §4's dependency gate, where headless skips them.
|
|
94
113
|
|
|
95
|
-
### §
|
|
114
|
+
### §6: Loop Completion
|
|
96
115
|
|
|
97
|
-
When all Tier A skills in `execution_order` are processed (completed, failed, or skipped):
|
|
116
|
+
When all Tier A skills in `execution_order` are processed (completed, failed, or skipped), write the stage:
|
|
98
117
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
118
|
+
```
|
|
119
|
+
uv run {stateScript} set-stage --state-file {stateFile} --stage 4
|
|
120
|
+
```
|
|
102
121
|
|
|
103
122
|
## OUTPUT
|
|
104
123
|
|
|
@@ -2,10 +2,13 @@
|
|
|
2
2
|
nextStepFile: 'step-07-capstone.md'
|
|
3
3
|
stateSchemaFile: 'assets/campaign-state-schema.json'
|
|
4
4
|
stateFile: '{campaignWorkspacePath}/_campaign-state.yaml'
|
|
5
|
-
backupFile: '{campaignWorkspacePath}/_campaign-state.yaml.bak'
|
|
6
5
|
briefFile: '{campaignWorkspacePath}/campaign-brief.yaml'
|
|
7
6
|
batchFile: '{campaignWorkspacePath}/_batch-input.txt'
|
|
7
|
+
batchMapFile: '{campaignWorkspacePath}/_batch-map.json'
|
|
8
|
+
batchResultsFile: '{campaignWorkspacePath}/_batch-results.json'
|
|
9
|
+
decisionLogFile: '{campaignWorkspacePath}/_campaign-decision-log.md'
|
|
8
10
|
batchScript: 'scripts/campaign-render-batch.py'
|
|
11
|
+
stateScript: 'scripts/campaign-state.py'
|
|
9
12
|
validateScript: 'scripts/campaign-validate-state.py'
|
|
10
13
|
---
|
|
11
14
|
|
|
@@ -19,43 +22,43 @@ Batch all Tier B skills through QS `--batch` mode, recording per-skill results i
|
|
|
19
22
|
|
|
20
23
|
## RULES
|
|
21
24
|
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
- Update `campaign.current_stage` to `5`.
|
|
26
|
-
- If `{headless_mode}` is true, auto-proceed through confirmation gates. QS `--batch` implies headless.
|
|
25
|
+
- Write `campaign.current_stage` = 5 only in this stage's final state write, after every result is recorded: step-resume resumes at `current_stage + 1`, so an early write skips unfinished work. An interrupted batch needs no stage write: its skills stay `active`, and resume sends an active Tier B skill back to this stage.
|
|
26
|
+
- Write state and decision-log entries only through `{stateScript}`, and on a non-zero exit HALT with the same code (State Contract in `references/campaign-contracts.md`). A log entry is `uv run {stateScript} log --log-file {decisionLogFile} --type <decision|auto|event> --text '<entry>'`.
|
|
27
|
+
- If `{headless_mode}` is true, emit this stage's progress events, and at any HARD HALT the error envelope, per `references/campaign-contracts.md`. QS `--batch` implies headless.
|
|
27
28
|
|
|
28
29
|
## TASKS
|
|
29
30
|
|
|
30
|
-
### §1
|
|
31
|
+
### §1: Read + Validate State
|
|
31
32
|
|
|
32
33
|
Load `{stateFile}`. Run `uv run {validateScript} --state-file {stateFile}`; on non-zero, HALT (exit 3) with the script's `errors[]`.
|
|
33
34
|
|
|
34
|
-
### §2
|
|
35
|
+
### §2: Read Directive
|
|
35
36
|
|
|
36
|
-
If `campaign.directive_path` is set in state,
|
|
37
|
+
If `campaign.directive_path` is set in state, the batch script applies its `## Skip List` itself (§3), so do not filter skills by hand. Read any other section as campaign-wide context, per the directive contract in `references/campaign-directive-spec.md`. If the file is not found, continue without error (directive is optional).
|
|
37
38
|
|
|
38
|
-
### §3
|
|
39
|
+
### §3: Select Tier B Skills and Write the Batch File
|
|
39
40
|
|
|
40
|
-
|
|
41
|
+
The batch script selects the Tier B skills (pending ones, and active ones an interrupted batch left behind), leaves out the ones the directive's Skip List names, and writes the batch file and its line-to-skill map: select and format nothing by hand. Pass `--directive-file` when state sets `campaign.directive_path`:
|
|
41
42
|
|
|
42
|
-
|
|
43
|
+
```
|
|
44
|
+
uv run {batchScript} --state-file {stateFile} --brief-file {briefFile} -o {batchFile} --map {batchMapFile} [--directive-file <campaign.directive_path>]
|
|
45
|
+
```
|
|
43
46
|
|
|
44
|
-
|
|
47
|
+
Its JSON summary on stderr gives `count`, the skill of each line in order (`skills`), the skills the Skip List left out (`skipped_by_directive`, each with its `reason`) and the hints left off a line (`dropped_hints`: a language or scope hint quick-skill could not read as one word).
|
|
45
48
|
|
|
46
|
-
|
|
49
|
+
HALT on non-zero exit: exit code 8 (`missing-brief`) when the brief is missing/unreadable **or** a selected Tier B skill has no matching brief target; exit code 2 (`invalid-input`) on a state file/parse error or a directive that cannot be read.
|
|
47
50
|
|
|
48
|
-
|
|
49
|
-
uv run {batchScript} --state-file {stateFile} --brief-file {briefFile} -o {batchFile}
|
|
50
|
-
```
|
|
51
|
+
Log each `skipped_by_directive` entry as "directive Skip List: {name} ({reason})" and each `dropped_hints` entry as "batch: {skill} built without its {hint} `{value}` (quick-skill reads a hint as one word)", both type `event`.
|
|
51
52
|
|
|
52
|
-
|
|
53
|
+
### §4: Execute QS Batch
|
|
53
54
|
|
|
54
|
-
|
|
55
|
+
Record the batch's start from the map, so no skill is marked by hand:
|
|
55
56
|
|
|
56
|
-
|
|
57
|
+
```
|
|
58
|
+
uv run {stateScript} apply-batch --state-file {stateFile} --map-file {batchMapFile} --start
|
|
59
|
+
```
|
|
57
60
|
|
|
58
|
-
|
|
61
|
+
It marks each `skipped_by_directive` skill `skipped` and each batched skill `active`, stamping `started_at` from the clock unless an interrupted batch already set it. If the §3 `count` is 0, add `--stage 5` to this call and chain to `{nextStepFile}`: the batch stage completes at once when every Tier B skill is already handled.
|
|
59
62
|
|
|
60
63
|
Invoke QS in `--batch` mode with the generated batch file:
|
|
61
64
|
|
|
@@ -63,25 +66,29 @@ Invoke QS in `--batch` mode with the generated batch file:
|
|
|
63
66
|
skf-quick-skill --batch {batchFile}
|
|
64
67
|
```
|
|
65
68
|
|
|
66
|
-
QS `--batch` implies `--headless`.
|
|
69
|
+
QS `--batch` implies `--headless`. When the batch ends it prints a `batch_summary` event on stderr: keep its `summary_path`, the batch summary file that holds each target's result.
|
|
70
|
+
|
|
71
|
+
### §5: Record Results
|
|
67
72
|
|
|
68
|
-
|
|
73
|
+
Join the batch summary to the skills by line number, never by matching QS output to skills by hand:
|
|
69
74
|
|
|
70
|
-
|
|
75
|
+
```
|
|
76
|
+
uv run {batchScript} --record <summary_path> --map {batchMapFile} > {batchResultsFile}
|
|
77
|
+
```
|
|
71
78
|
|
|
72
|
-
|
|
73
|
-
- Set `status` to `"completed"`
|
|
74
|
-
- Set `completed_at` to current ISO-8601 with timezone
|
|
75
|
-
- Record `quality_score` from QS output
|
|
76
|
-
- Record `skill_path` from QS output
|
|
77
|
-
2. If QS reports failure:
|
|
78
|
-
- Set `status` to `"failed"`
|
|
79
|
+
When that call exits 0, record the results and the stage in one write:
|
|
79
80
|
|
|
80
|
-
|
|
81
|
+
```
|
|
82
|
+
uv run {stateScript} apply-batch --state-file {stateFile} --map-file {batchMapFile} --results-file {batchResultsFile} --stage 5
|
|
83
|
+
```
|
|
81
84
|
|
|
82
|
-
|
|
85
|
+
A `completed` result sets the skill `completed`, with `completed_at` from the clock, its `quality_score` (the skill-check score QS records, not a test-skill score) and its `skill_path`; a `failed` one sets it `failed`. Log each entry of the helper's `failed[]` with its `error_code` (`no-batch-result` when the summary holds no result for its line), type `event`.
|
|
83
86
|
|
|
84
|
-
|
|
87
|
+
When QS printed no `batch_summary` event (run no record call), or the record call exits 2 (a missing summary or map, or a summary that belongs to another batch file), fail every skill the map lists instead, and log why: never guess which target built which skill.
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
uv run {stateScript} apply-batch --state-file {stateFile} --map-file {batchMapFile} --no-results --stage 5
|
|
91
|
+
```
|
|
85
92
|
|
|
86
93
|
## OUTPUT
|
|
87
94
|
|
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
nextStepFile: 'step-08-verify.md'
|
|
3
3
|
stateSchemaFile: 'assets/campaign-state-schema.json'
|
|
4
4
|
stateFile: '{campaignWorkspacePath}/_campaign-state.yaml'
|
|
5
|
-
|
|
5
|
+
decisionLogFile: '{campaignWorkspacePath}/_campaign-decision-log.md'
|
|
6
|
+
gateScript: 'scripts/campaign-quality-gate.py'
|
|
7
|
+
manifestScript: 'scripts/campaign-parse-manifest.py'
|
|
8
|
+
stateScript: 'scripts/campaign-state.py'
|
|
6
9
|
validateScript: 'scripts/campaign-validate-state.py'
|
|
7
10
|
---
|
|
8
11
|
|
|
@@ -12,51 +15,63 @@ validateScript: 'scripts/campaign-validate-state.py'
|
|
|
12
15
|
|
|
13
16
|
## STEP GOAL:
|
|
14
17
|
|
|
15
|
-
Compose a capstone stack skill from
|
|
18
|
+
Compose a capstone stack skill from the completed individual skills that clear the quality gate, using SS compose-mode. The capstone represents the final integrated view of the campaign's exported skills: a single stack skill that documents how the constituent libraries connect.
|
|
16
19
|
|
|
17
20
|
## RULES
|
|
18
21
|
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
- Update `campaign.current_stage` to `6`.
|
|
23
|
-
- If `{headless_mode}` is true, auto-proceed through confirmation gates. SS compose-mode supports headless.
|
|
22
|
+
- Write `campaign.current_stage` = 6 only in this stage's final state write (§4), after the capstone is recorded: step-resume resumes at `current_stage + 1`, so an early write skips unfinished work.
|
|
23
|
+
- Write state and decision-log entries only through `{stateScript}`, and on a non-zero exit HALT with the same code (State Contract in `references/campaign-contracts.md`). A log entry is `uv run {stateScript} log --log-file {decisionLogFile} --type <decision|auto|event> --text '<entry>'`.
|
|
24
|
+
- If `{headless_mode}` is true, emit this stage's progress events, and at any HARD HALT the error envelope, per `references/campaign-contracts.md`. SS compose-mode runs headless.
|
|
24
25
|
|
|
25
26
|
## TASKS
|
|
26
27
|
|
|
27
|
-
### §1
|
|
28
|
+
### §1: Read + Validate State
|
|
28
29
|
|
|
29
30
|
Load `{stateFile}`. Run `uv run {validateScript} --state-file {stateFile}`; on non-zero, HALT (exit 3) with the script's `errors[]`.
|
|
30
31
|
|
|
31
|
-
### §2
|
|
32
|
+
### §2: Collect Completed Skills
|
|
32
33
|
|
|
33
|
-
|
|
34
|
+
Classify the completed skills (Tier A from step-05, Tier B from step-06) against the quality gate as Export will, passing `--directive-file` when state sets `campaign.directive_path`; never compare scores by hand:
|
|
34
35
|
|
|
35
|
-
|
|
36
|
+
```
|
|
37
|
+
uv run {gateScript} classify --state-file {stateFile} [--directive-file <campaign.directive_path>]
|
|
38
|
+
```
|
|
36
39
|
|
|
37
|
-
|
|
40
|
+
The capstone composes the skills in its `export[]` (the `pass` and `fallback` verdicts), so it never describes a skill the gate keeps from export: log each `excluded[]` skill as "capstone: {name} left out, below the quality gate ({reason})". Name each composed skill by the `export_name` of its row in `skills[]` (the skill folder its build wrote), as Export does. On exit 2 (an override that breaks the gate, or a directive that cannot be read), HALT (exit code 2, `invalid-input`) with its `error`.
|
|
38
41
|
|
|
39
|
-
|
|
42
|
+
If `export[]` is empty (no completed skill, or none clears the gate), do NOT HALT: a campaign where everything failed is exactly when the operator most needs the downstream diagnostic report. Warn ("No skill clears the quality gate: skipping capstone composition; verification and the campaign report will still run so failures are explained"), log the skip (type `event`), and go to §4 with no capstone, so the chain continues to verify, refine, export and the report. step-10 (export) and step-11 (report) already handle the zero-completed case.
|
|
40
43
|
|
|
41
|
-
|
|
42
|
-
- `campaign.name` as the stack identifier
|
|
44
|
+
### §3: Invoke SS Compose-Mode
|
|
43
45
|
|
|
44
|
-
|
|
46
|
+
Invoke `skf-create-stack-skill` with `--headless` and these inputs, so it asks nothing and prints its result envelope:
|
|
45
47
|
|
|
46
|
-
|
|
48
|
+
- `mode`: `compose`
|
|
49
|
+
- `skills`: the §2 `export_name` values, comma-separated (compose mode takes them as its constituent skill folders)
|
|
50
|
+
- `stack_name`: the `stack_name` that `uv run {manifestScript} --stack-name {stateFile}` prints, the campaign name as a skill name cut to leave room for the `-stack` SS appends; when it prints null, leave the input out and SS names the stack `{project_name}-stack`
|
|
51
|
+
- `architecture_doc_path`: `campaign.architecture_doc_path`, only when state sets it
|
|
47
52
|
|
|
48
|
-
|
|
53
|
+
Keep the `SKF_STACK_RESULT_JSON` line it prints for §4, which records it. On `status` `error`, or no envelope, log its `halt_reason` (or "no result envelope", type `event`): verification and the campaign report still run.
|
|
49
54
|
|
|
50
|
-
|
|
51
|
-
- `campaign.capstone.quality_score` — quality score (from SS result)
|
|
52
|
-
- `campaign.capstone.verified` — `null` for now; set by the verify stage (step-08) once the stack is checked
|
|
53
|
-
- `campaign.capstone.completed_at` — current ISO-8601 with timezone
|
|
55
|
+
### §4: Record the Capstone and Complete the Stage
|
|
54
56
|
|
|
55
|
-
|
|
57
|
+
Record the capstone outcome and the stage in one write, passing the §3 envelope line to the helper, which reads it (never copy its fields by hand):
|
|
56
58
|
|
|
57
|
-
|
|
59
|
+
```
|
|
60
|
+
uv run {stateScript} set-campaign --state-file {stateFile} --capstone - --stage 6 <<'SKF_RESULT'
|
|
61
|
+
<the SKF_STACK_RESULT_JSON line SS printed>
|
|
62
|
+
SKF_RESULT
|
|
63
|
+
```
|
|
58
64
|
|
|
59
|
-
|
|
65
|
+
From a `success` envelope it sets `campaign.capstone`, the campaign-level summary (the composed skill itself lives at `skill_path`):
|
|
66
|
+
|
|
67
|
+
- `campaign.capstone.skill_path`: `skill_package` from the SS envelope
|
|
68
|
+
- `campaign.capstone.quality_score`: `quality_score` from the SS envelope (the skill-check score SS records, null when skill-check did not run; it is not a test-skill score)
|
|
69
|
+
- `campaign.capstone.verified`: `null` for now; set by the verify stage (step-08) once the stack is checked
|
|
70
|
+
- `campaign.capstone.completed_at`: the time of the write, from the clock
|
|
71
|
+
|
|
72
|
+
An `error` envelope sets `campaign.capstone` to `null` (the helper names it in `not_recorded`). When §2 found no skill to compose, or SS printed no envelope, record no capstone instead: `uv run {stateScript} set-campaign --state-file {stateFile} --no-capstone --stage 6`.
|
|
73
|
+
|
|
74
|
+
The capstone is a derived artifact: it is **not** tracked as a skill entry in the `skills[]` array. The constituent skill list and any verbose detail are reported in the step output and are available to downstream steps (verify, refine).
|
|
60
75
|
|
|
61
76
|
## OUTPUT
|
|
62
77
|
|