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
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://github.com/armelhbobdad/bmad-module-skill-forge/src/shared/scripts/schemas/skf-audit-result-envelope.v1.json",
|
|
4
|
+
"title": "SKF_AUDIT_RESULT_JSON envelope (v1)",
|
|
5
|
+
"description": "Single-line JSON document skf-audit-skill emits when {headless_mode} is true, prefixed with the literal 'SKF_AUDIT_RESULT_JSON: ': once on stdout when step 6 (report) finishes, which the health check displays as the run's last line, and once on stderr at every HARD HALT (status error). The shared emitter, skf-emit-result-envelope.py, builds every line from the payload a stage stages in the run folder, folds in the auto-decisions and warnings the run recorded there, derives exit_code from halt_reason, stamps run_id and result_path, writes the result files on success, and checks the line against this schema, so the model never types it. The skill's references/headless-contract.md holds the exit-code table and its stage files show the halt command.",
|
|
6
|
+
"$defs": {
|
|
7
|
+
"skf-envelope": {
|
|
8
|
+
"description": "The shared emitter's settings for this workflow, read by skf-emit-result-envelope.py: the workflow, the line's prefix, the wrapper, the status a halt carries, the exit code of each halt_reason and the result file stem. Nothing in the schema references this entry, so it constrains no envelope.",
|
|
9
|
+
"const": {
|
|
10
|
+
"workflow": "skf-audit-skill",
|
|
11
|
+
"prefix": "SKF_AUDIT_RESULT_JSON",
|
|
12
|
+
"wrapper": null,
|
|
13
|
+
"halt_status": "error",
|
|
14
|
+
"exit_codes": {
|
|
15
|
+
"input-missing": 2,
|
|
16
|
+
"skill-not-found": 3,
|
|
17
|
+
"not-skf-output": 3,
|
|
18
|
+
"forge-tier-missing": 3,
|
|
19
|
+
"no-baseline": 3,
|
|
20
|
+
"source-dir-missing": 3,
|
|
21
|
+
"provenance-invalid": 3,
|
|
22
|
+
"source-unreadable": 3,
|
|
23
|
+
"helper-missing": 3,
|
|
24
|
+
"write-failed": 4,
|
|
25
|
+
"user-cancelled": 6
|
|
26
|
+
},
|
|
27
|
+
"success_exit_code": 0,
|
|
28
|
+
"result_file": "audit-skill-result"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"type": "object",
|
|
33
|
+
"additionalProperties": false,
|
|
34
|
+
"required": [
|
|
35
|
+
"status",
|
|
36
|
+
"skill_name",
|
|
37
|
+
"drift_score",
|
|
38
|
+
"report_path",
|
|
39
|
+
"next_workflow",
|
|
40
|
+
"audit_ref",
|
|
41
|
+
"upstream_moved",
|
|
42
|
+
"upstream_ref",
|
|
43
|
+
"exit_code",
|
|
44
|
+
"halt_reason",
|
|
45
|
+
"run_id",
|
|
46
|
+
"result_path"
|
|
47
|
+
],
|
|
48
|
+
"properties": {
|
|
49
|
+
"status": {
|
|
50
|
+
"type": "string",
|
|
51
|
+
"enum": ["success", "error"],
|
|
52
|
+
"description": "'success' when step 6 wrote the drift report and its result contract. 'error' on any HARD HALT."
|
|
53
|
+
},
|
|
54
|
+
"skill_name": {
|
|
55
|
+
"type": ["string", "null"],
|
|
56
|
+
"minLength": 1,
|
|
57
|
+
"default": null,
|
|
58
|
+
"description": "The audited skill. Null when the run halted before one was named (input-missing)."
|
|
59
|
+
},
|
|
60
|
+
"drift_score": {
|
|
61
|
+
"type": ["string", "null"],
|
|
62
|
+
"enum": ["CLEAN", "MINOR", "SIGNIFICANT", "CRITICAL", null],
|
|
63
|
+
"default": null,
|
|
64
|
+
"description": "The drift_score skf-severity-classify.py saved in step 5's severity.json. Null when the run halted before severity classification."
|
|
65
|
+
},
|
|
66
|
+
"report_path": {
|
|
67
|
+
"type": ["string", "null"],
|
|
68
|
+
"minLength": 1,
|
|
69
|
+
"default": null,
|
|
70
|
+
"description": "The drift report, drift-report-<timestamp>.md in the audited version's forge folder. Null when the run halted before step 1 wrote it, or when the report write failed."
|
|
71
|
+
},
|
|
72
|
+
"next_workflow": {
|
|
73
|
+
"type": ["string", "null"],
|
|
74
|
+
"enum": ["update-skill", null],
|
|
75
|
+
"default": null,
|
|
76
|
+
"description": "'update-skill' when the classification counts a CRITICAL or HIGH finding, or when upstream_moved is true (the skill is built from an older ref than the remote now names), so a maintain pipeline reaches update-skill after an upstream release; null otherwise and on a halt."
|
|
77
|
+
},
|
|
78
|
+
"audit_ref": {
|
|
79
|
+
"type": ["string", "null"],
|
|
80
|
+
"minLength": 1,
|
|
81
|
+
"default": null,
|
|
82
|
+
"description": "The ref the audit read: the baseline ref when it stayed on the baseline, the upstream ref when step 1's upstream-drift gate chose [C] and the run read that ref from a private source tree. Null before step 1 decided it."
|
|
83
|
+
},
|
|
84
|
+
"upstream_moved": {
|
|
85
|
+
"type": ["boolean", "null"],
|
|
86
|
+
"default": null,
|
|
87
|
+
"description": "True when step 1's one skf-check-workspace-drift.py upstream call found that the remote moved past the commit and ref the skill was built from (status moved), false when it found them unchanged, null when the check was skipped (no git source, no baseline commit or ref, a stack skill, a docs-only skill) or could not reach the remote."
|
|
88
|
+
},
|
|
89
|
+
"upstream_ref": {
|
|
90
|
+
"type": ["string", "null"],
|
|
91
|
+
"minLength": 1,
|
|
92
|
+
"default": null,
|
|
93
|
+
"description": "When upstream_moved is true, the ref the remote moved to (the newer tag, the moved tag or branch, or 'HEAD' for the default branch): pass it to update-skill as --target-ref. Null otherwise."
|
|
94
|
+
},
|
|
95
|
+
"exit_code": {
|
|
96
|
+
"type": "integer",
|
|
97
|
+
"enum": [0, 2, 3, 4, 6],
|
|
98
|
+
"description": "Process exit code matching the Exit Codes table of the skill's references/headless-contract.md, derived from halt_reason: null gives 0, input-missing 2, skill-not-found, not-skf-output, forge-tier-missing, no-baseline, source-dir-missing, provenance-invalid, source-unreadable and helper-missing 3, write-failed 4, user-cancelled 6."
|
|
99
|
+
},
|
|
100
|
+
"halt_reason": {
|
|
101
|
+
"type": ["string", "null"],
|
|
102
|
+
"enum": [
|
|
103
|
+
null,
|
|
104
|
+
"input-missing",
|
|
105
|
+
"skill-not-found",
|
|
106
|
+
"not-skf-output",
|
|
107
|
+
"forge-tier-missing",
|
|
108
|
+
"no-baseline",
|
|
109
|
+
"source-dir-missing",
|
|
110
|
+
"provenance-invalid",
|
|
111
|
+
"source-unreadable",
|
|
112
|
+
"helper-missing",
|
|
113
|
+
"write-failed",
|
|
114
|
+
"user-cancelled"
|
|
115
|
+
],
|
|
116
|
+
"description": "Null on success. One of the documented HALT classes on error, so a pipeline branches on the failure class without parsing the prose message."
|
|
117
|
+
},
|
|
118
|
+
"run_id": {
|
|
119
|
+
"type": ["string", "null"],
|
|
120
|
+
"minLength": 1,
|
|
121
|
+
"description": "The run's id, stamped by the emitter from the run folder name: the run's timestamp (YYYYMMDD-HHmmss), the stamp the drift report's file name carries. Null for a halt before the run folder exists."
|
|
122
|
+
},
|
|
123
|
+
"result_path": {
|
|
124
|
+
"type": ["string", "null"],
|
|
125
|
+
"minLength": 1,
|
|
126
|
+
"description": "The per-run result file the emitter wrote in the audited version's forge folder, audit-skill-result-<YYYYMMDD-HHmmss>.json (UTC), beside its audit-skill-result-latest.json copy. Stamped by the emitter, never typed. Null on every halt, which writes no result file, and when the write failed (warnings say why)."
|
|
127
|
+
},
|
|
128
|
+
"headless_decisions": {
|
|
129
|
+
"type": "array",
|
|
130
|
+
"items": {
|
|
131
|
+
"type": "object",
|
|
132
|
+
"additionalProperties": false,
|
|
133
|
+
"required": ["gate", "default_action", "taken_action", "reason"],
|
|
134
|
+
"properties": {
|
|
135
|
+
"gate": {
|
|
136
|
+
"type": "string",
|
|
137
|
+
"enum": ["init.manifest-lags-link", "init.upstream-drift", "init.baseline-confirm"],
|
|
138
|
+
"description": "The gate that auto-resolved: step 1's manifest-vs-link gate, its upstream-drift gate, or its baseline confirm gate (init.baseline-confirm), which a run reaches only on a baseline doubt: the forge tier below the compile tier, or a provenance map more than 90 days old. Each records its decision in the run sink the moment it decides."
|
|
139
|
+
},
|
|
140
|
+
"default_action": {
|
|
141
|
+
"type": "string",
|
|
142
|
+
"minLength": 1,
|
|
143
|
+
"description": "The action documented as the gate's default: 'N' (audit the link's version) or 'C' (audit the upstream ref, or continue past the baseline doubt)."
|
|
144
|
+
},
|
|
145
|
+
"taken_action": {
|
|
146
|
+
"type": "string",
|
|
147
|
+
"minLength": 1,
|
|
148
|
+
"description": "The action the run took: the default, or the pre-supplied upstream_drift_choice ('C', 'S' or 'X')."
|
|
149
|
+
},
|
|
150
|
+
"reason": {
|
|
151
|
+
"type": "string",
|
|
152
|
+
"minLength": 1,
|
|
153
|
+
"description": "Human-readable rationale, such as 'headless: upstream moved v1.2.0 -> v1.3.0; auditing v1.3.0'."
|
|
154
|
+
},
|
|
155
|
+
"evidence": {
|
|
156
|
+
"type": "object",
|
|
157
|
+
"additionalProperties": true,
|
|
158
|
+
"description": "Optional gate-specific data, such as the baseline and upstream refs."
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
"description": "Optional. One entry per gate that auto-resolved during the run, read from the run sink, so a halt reports the decisions taken before it. Present only when there is at least one."
|
|
163
|
+
},
|
|
164
|
+
"warnings": {
|
|
165
|
+
"type": "array",
|
|
166
|
+
"items": { "type": "string", "minLength": 1 },
|
|
167
|
+
"description": "Optional. Non-fatal anomalies the run recorded in its sink or the emitter raised, one string each, starting with its code: upstream_tree_unavailable when [C] could not read the upstream ref into a private tree and the audit stayed on the baseline, source_tree_not_removed when the private tree could not be removed, recipe_runner_failed (with the recipe runner's error line) when the runner left no JSON and named an error on stderr, so re-index extracted without it, public_surface_not_applied (with the rule's problem) when re-index could read no public surface for a public-api skill (Quick tier, a runner that could not run, an incomplete run, one with errors, or an entry point it could not trace), so structural diff reported every export the provenance map does not hold as added, doc_fetch_failed and doc_not_hashed (each with its count) when a docs-only skill's score leaves out documents that could not be fetched or have no recorded hash, new_files_not_checked (with the reason) when the Script/Asset Drift check looked for no new script, asset or document because the skill has no brief it could read or a helper it needs could not be loaded, customization_resolver_unavailable when the customization resolver failed and only the bundled customize.toml applied, and result_file_write_failed when a result file could not be written. Present only when there is at least one."
|
|
168
|
+
},
|
|
169
|
+
"error": {
|
|
170
|
+
"type": "object",
|
|
171
|
+
"additionalProperties": false,
|
|
172
|
+
"required": ["phase", "reason"],
|
|
173
|
+
"properties": {
|
|
174
|
+
"phase": {
|
|
175
|
+
"type": "string",
|
|
176
|
+
"minLength": 1,
|
|
177
|
+
"description": "Where the run halted: the step and gate, for example 'init:skill-path' or 'report:write'."
|
|
178
|
+
},
|
|
179
|
+
"reason": {
|
|
180
|
+
"type": "string",
|
|
181
|
+
"minLength": 1,
|
|
182
|
+
"description": "The halt message the step displayed, on one line."
|
|
183
|
+
},
|
|
184
|
+
"path": {
|
|
185
|
+
"type": "string",
|
|
186
|
+
"description": "Optional path the failed operation targeted."
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
"description": "Present on a HARD HALT only: where the run stopped and why. Pipelines branch on halt_reason and read error for the diagnostic."
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
@@ -2,7 +2,30 @@
|
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
3
|
"$id": "https://github.com/armelhbobdad/bmad-module-skill-forge/src/shared/scripts/schemas/skf-brief-result-envelope.v1.json",
|
|
4
4
|
"title": "SKF_BRIEF_RESULT_JSON envelope (v1)",
|
|
5
|
-
"description": "Single-line JSON document
|
|
5
|
+
"description": "Single-line JSON document skf-brief-skill prints when {headless_mode} is true or the run is in [auto] mode, at the end of a successful run and at every HARD HALT, prefixed with the literal 'SKF_BRIEF_RESULT_JSON: '. Pipelines grep one line out of the workflow log to branch on the brief outcome without parsing prose. Schema mirrors the contract in src/skf-brief-skill/references/invocation-contract.md (Result Contract).",
|
|
6
|
+
"$defs": {
|
|
7
|
+
"skf-envelope": {
|
|
8
|
+
"description": "The shared emitter's settings for this workflow, read by skf-emit-result-envelope.py: the workflow, the line's prefix, the wrapper, the status a halt carries, the exit code of each halt_reason and the result file stem. Nothing in the schema references this entry, so it constrains no envelope.",
|
|
9
|
+
"const": {
|
|
10
|
+
"workflow": "skf-brief-skill",
|
|
11
|
+
"prefix": "SKF_BRIEF_RESULT_JSON",
|
|
12
|
+
"wrapper": null,
|
|
13
|
+
"halt_status": "error",
|
|
14
|
+
"exit_codes": {
|
|
15
|
+
"input-missing": 2,
|
|
16
|
+
"input-invalid": 2,
|
|
17
|
+
"forge-tier-missing": 3,
|
|
18
|
+
"target-inaccessible": 3,
|
|
19
|
+
"gh-auth-failed": 3,
|
|
20
|
+
"write-failed": 4,
|
|
21
|
+
"overwrite-cancelled": 5,
|
|
22
|
+
"user-cancelled": 6
|
|
23
|
+
},
|
|
24
|
+
"success_exit_code": 0,
|
|
25
|
+
"result_file": null
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
},
|
|
6
29
|
"type": "object",
|
|
7
30
|
"additionalProperties": false,
|
|
8
31
|
"required": ["status", "brief_path", "skill_name", "version", "language", "scope_type", "exit_code", "halt_reason", "mode"],
|
|
@@ -10,7 +33,7 @@
|
|
|
10
33
|
"status": {
|
|
11
34
|
"type": "string",
|
|
12
35
|
"enum": ["success", "error"],
|
|
13
|
-
"description": "'success'
|
|
36
|
+
"description": "'success' once the run has written the brief (step 5) or, in [auto] mode, the user or a headless run approved it (step 1b). 'error' on any HARD HALT."
|
|
14
37
|
},
|
|
15
38
|
"brief_path": {
|
|
16
39
|
"type": ["string", "null"],
|
|
@@ -19,7 +42,7 @@
|
|
|
19
42
|
"skill_name": {
|
|
20
43
|
"type": "string",
|
|
21
44
|
"minLength": 1,
|
|
22
|
-
"description": "Brief's skill_name field
|
|
45
|
+
"description": "Brief's skill_name field, present in every envelope (success and error): the literal 'unknown' on a halt that fires before step 1 resolves the name."
|
|
23
46
|
},
|
|
24
47
|
"version": {
|
|
25
48
|
"type": ["string", "null"],
|
|
@@ -37,7 +60,7 @@
|
|
|
37
60
|
"exit_code": {
|
|
38
61
|
"type": "integer",
|
|
39
62
|
"enum": [0, 2, 3, 4, 5, 6],
|
|
40
|
-
"description": "Process exit code matching the
|
|
63
|
+
"description": "Process exit code matching the Exit Codes table in src/skf-brief-skill/references/invocation-contract.md. Derived deterministically from halt_reason: null→0, input-missing/input-invalid→2, forge-tier-missing/target-inaccessible/gh-auth-failed→3, write-failed→4, overwrite-cancelled→5, user-cancelled→6."
|
|
41
64
|
},
|
|
42
65
|
"halt_reason": {
|
|
43
66
|
"type": ["string", "null"],
|
|
@@ -58,6 +81,11 @@
|
|
|
58
81
|
"type": ["string", "null"],
|
|
59
82
|
"enum": ["auto", null],
|
|
60
83
|
"description": "'auto' when BS was invoked with the [auto] bracket modifier (pipeline auto-brief generation). Null otherwise (interactive or headless-without-auto)."
|
|
84
|
+
},
|
|
85
|
+
"warnings": {
|
|
86
|
+
"type": "array",
|
|
87
|
+
"items": { "type": "string", "minLength": 1 },
|
|
88
|
+
"description": "Optional. Non-fatal anomalies surfaced during the run, one string each, such as customization_resolver_unavailable when the customization resolver could not apply the _bmad/custom/ overrides. Present only when the run recorded at least one, so an envelope without warnings is unchanged."
|
|
61
89
|
}
|
|
62
90
|
}
|
|
63
91
|
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://github.com/armelhbobdad/bmad-module-skill-forge/src/shared/scripts/schemas/skf-campaign-result-envelope.v1.json",
|
|
4
|
+
"title": "SKF_CAMPAIGN_RESULT_JSON envelope (v1)",
|
|
5
|
+
"description": "Single-line JSON document skf-campaign emits when {headless_mode} is true, prefixed with the literal 'SKF_CAMPAIGN_RESULT_JSON: ': once at the end of a campaign (step 11, after its final state write and the on_complete hook), which the end-of-run health check displays as the run's last line, again as the last line of a headless resume that finds the campaign already complete, and once on stderr at every HARD HALT (status error). The shared emitter, skf-emit-result-envelope.py, builds every line from the payload the step stages (at the end, the context campaign-report.py writes; at a HARD HALT, the one campaign-state.py halt-payload prints), derives exit_code from halt_reason and checks the line against this schema, so the model never types it. This schema is the one definition of the envelope: the skill's references/campaign-contracts.md lists the exit codes and holds the halt command.",
|
|
6
|
+
"$defs": {
|
|
7
|
+
"skf-envelope": {
|
|
8
|
+
"description": "The shared emitter's settings for this workflow, read by skf-emit-result-envelope.py: the workflow, the line's prefix, the wrapper, the status a halt carries and the exit code of each halt_reason. Campaign writes no result file of its own (its state, report and decision log hold the record). Nothing in the schema references this entry, so it constrains no envelope.",
|
|
9
|
+
"const": {
|
|
10
|
+
"workflow": "skf-campaign",
|
|
11
|
+
"prefix": "SKF_CAMPAIGN_RESULT_JSON",
|
|
12
|
+
"wrapper": null,
|
|
13
|
+
"halt_status": "error",
|
|
14
|
+
"exit_codes": {
|
|
15
|
+
"invalid-input": 2,
|
|
16
|
+
"invalid-state": 3,
|
|
17
|
+
"circular-deps": 4,
|
|
18
|
+
"invalid-pin": 5,
|
|
19
|
+
"inaccessible-repo": 6,
|
|
20
|
+
"dependency-deadlock": 7,
|
|
21
|
+
"missing-brief": 8,
|
|
22
|
+
"corrupt-state": 9,
|
|
23
|
+
"report-failure": 10,
|
|
24
|
+
"export-cancelled": 11,
|
|
25
|
+
"user-cancelled": 12,
|
|
26
|
+
"dependency-blocked": 13
|
|
27
|
+
},
|
|
28
|
+
"success_exit_code": 0,
|
|
29
|
+
"result_file": null
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"type": "object",
|
|
34
|
+
"additionalProperties": false,
|
|
35
|
+
"required": [
|
|
36
|
+
"status",
|
|
37
|
+
"exit_code",
|
|
38
|
+
"halt_reason",
|
|
39
|
+
"skills_completed",
|
|
40
|
+
"skills_failed",
|
|
41
|
+
"quality_scores",
|
|
42
|
+
"export_verdicts",
|
|
43
|
+
"skills_excluded",
|
|
44
|
+
"campaign_report_path",
|
|
45
|
+
"decision_log",
|
|
46
|
+
"duration"
|
|
47
|
+
],
|
|
48
|
+
"properties": {
|
|
49
|
+
"status": {
|
|
50
|
+
"type": "string",
|
|
51
|
+
"enum": ["success", "error"],
|
|
52
|
+
"description": "'success' when the campaign completed and its report was written. 'error' on any HARD HALT, and on the one degraded finish: a campaign that completed but whose report could not be generated (halt_reason report-failure, exit_code 10, campaign_report_path null), which keeps its state intact."
|
|
53
|
+
},
|
|
54
|
+
"exit_code": {
|
|
55
|
+
"type": "integer",
|
|
56
|
+
"enum": [0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13],
|
|
57
|
+
"description": "The campaign's exit code, derived from halt_reason: null gives 0, invalid-input 2, invalid-state 3, circular-deps 4, invalid-pin 5, inaccessible-repo 6, dependency-deadlock 7, missing-brief 8, corrupt-state 9, report-failure 10, export-cancelled 11, user-cancelled 12, dependency-blocked 13."
|
|
58
|
+
},
|
|
59
|
+
"halt_reason": {
|
|
60
|
+
"type": ["string", "null"],
|
|
61
|
+
"enum": [
|
|
62
|
+
null,
|
|
63
|
+
"invalid-input",
|
|
64
|
+
"invalid-state",
|
|
65
|
+
"circular-deps",
|
|
66
|
+
"invalid-pin",
|
|
67
|
+
"inaccessible-repo",
|
|
68
|
+
"dependency-deadlock",
|
|
69
|
+
"missing-brief",
|
|
70
|
+
"corrupt-state",
|
|
71
|
+
"report-failure",
|
|
72
|
+
"export-cancelled",
|
|
73
|
+
"user-cancelled",
|
|
74
|
+
"dependency-blocked"
|
|
75
|
+
],
|
|
76
|
+
"description": "Null on success. The Exit Codes meaning of the halt otherwise, so a pipeline branches on the failure class without parsing the message; report-failure is the degraded finish described under status."
|
|
77
|
+
},
|
|
78
|
+
"phase": {
|
|
79
|
+
"type": "string",
|
|
80
|
+
"minLength": 1,
|
|
81
|
+
"description": "Present on a HARD HALT only: the kebab slug of the step where the campaign stopped, such as 'strategy' or 'skill-loop'."
|
|
82
|
+
},
|
|
83
|
+
"error": {
|
|
84
|
+
"type": "object",
|
|
85
|
+
"additionalProperties": false,
|
|
86
|
+
"required": ["code", "message"],
|
|
87
|
+
"properties": {
|
|
88
|
+
"code": {
|
|
89
|
+
"type": "string",
|
|
90
|
+
"minLength": 1,
|
|
91
|
+
"description": "The halt_reason."
|
|
92
|
+
},
|
|
93
|
+
"message": {
|
|
94
|
+
"type": "string",
|
|
95
|
+
"minLength": 1,
|
|
96
|
+
"description": "The halt message the step displayed, on one line."
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
"description": "Present on a HARD HALT only: why the campaign stopped. Pipelines branch on halt_reason and read error for the diagnostic."
|
|
100
|
+
},
|
|
101
|
+
"skills_completed": {
|
|
102
|
+
"type": "integer",
|
|
103
|
+
"minimum": 0,
|
|
104
|
+
"default": 0,
|
|
105
|
+
"description": "Skills whose status is completed: campaign-report.py's count at the end, campaign-state.py halt-payload's count at a HARD HALT (0 before the state exists)."
|
|
106
|
+
},
|
|
107
|
+
"skills_failed": {
|
|
108
|
+
"type": "integer",
|
|
109
|
+
"minimum": 0,
|
|
110
|
+
"default": 0,
|
|
111
|
+
"description": "Skills whose status is failed, counted as skills_completed is."
|
|
112
|
+
},
|
|
113
|
+
"quality_scores": {
|
|
114
|
+
"type": "object",
|
|
115
|
+
"additionalProperties": true,
|
|
116
|
+
"default": {},
|
|
117
|
+
"description": "Each completed skill's recorded score, by skill name: test-skill's for a Tier A skill, the skill-check score quick-skill records for a Tier B skill. Empty on a HARD HALT."
|
|
118
|
+
},
|
|
119
|
+
"export_verdicts": {
|
|
120
|
+
"type": ["object", "null"],
|
|
121
|
+
"additionalProperties": true,
|
|
122
|
+
"default": null,
|
|
123
|
+
"description": "Each completed skill's quality-gate verdict at Export, by skill name: pass, fallback or fail. Null when the gate could not be applied, and on a HARD HALT."
|
|
124
|
+
},
|
|
125
|
+
"skills_excluded": {
|
|
126
|
+
"type": ["array", "null"],
|
|
127
|
+
"items": { "type": "string", "minLength": 1 },
|
|
128
|
+
"default": null,
|
|
129
|
+
"description": "The completed skills the gate kept from export (verdict fail), so a completed skill is not taken for an exported one. Null when the gate could not be applied, and on a HARD HALT."
|
|
130
|
+
},
|
|
131
|
+
"skills_exported": {
|
|
132
|
+
"type": ["array", "null"],
|
|
133
|
+
"items": { "type": "string", "minLength": 1 },
|
|
134
|
+
"description": "Optional. The skills the Export stage exported (skf-export-skill exited 0), by campaign skill name, from the outcome campaign-state.py recorded for each one. Null when the Export stage did not run; absent on a HARD HALT."
|
|
135
|
+
},
|
|
136
|
+
"export_failures": {
|
|
137
|
+
"type": ["array", "null"],
|
|
138
|
+
"items": {
|
|
139
|
+
"type": "object",
|
|
140
|
+
"additionalProperties": false,
|
|
141
|
+
"required": ["skill", "halt_reason", "exit_code"],
|
|
142
|
+
"properties": {
|
|
143
|
+
"skill": { "type": "string", "minLength": 1 },
|
|
144
|
+
"halt_reason": { "type": ["string", "null"] },
|
|
145
|
+
"exit_code": { "type": ["integer", "null"] }
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
"description": "Optional. Each skill whose skf-export-skill call failed, with that call's halt_reason and exit code (null when it gave none). The campaign still ends with status success, so a CI job gates on this list. Null when the Export stage did not run; absent on a HARD HALT."
|
|
149
|
+
},
|
|
150
|
+
"campaign_report_path": {
|
|
151
|
+
"type": ["string", "null"],
|
|
152
|
+
"minLength": 1,
|
|
153
|
+
"default": null,
|
|
154
|
+
"description": "The campaign-report.md step 11 wrote. Null when it could not be written, and on a HARD HALT."
|
|
155
|
+
},
|
|
156
|
+
"decision_log": {
|
|
157
|
+
"type": ["string", "null"],
|
|
158
|
+
"minLength": 1,
|
|
159
|
+
"default": null,
|
|
160
|
+
"description": "The append-only _campaign-decision-log.md, whose typed entries record every operator decision, headless default and event. Null before the campaign workspace exists."
|
|
161
|
+
},
|
|
162
|
+
"duration": {
|
|
163
|
+
"type": ["string", "null"],
|
|
164
|
+
"minLength": 1,
|
|
165
|
+
"default": null,
|
|
166
|
+
"description": "Wall-clock time from campaign.started_at to its last state write before the report, as campaign-report.py formats it (such as '2h 5m 3s'). Null on a HARD HALT."
|
|
167
|
+
},
|
|
168
|
+
"warnings": {
|
|
169
|
+
"type": "array",
|
|
170
|
+
"items": { "type": "string", "minLength": 1 },
|
|
171
|
+
"description": "Optional. Non-fatal anomalies the emitter raised, one string each, starting with its code. Present only when there is at least one."
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|