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
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
---
|
|
2
|
-
# Static reference
|
|
3
|
-
# schema documentation is needed (
|
|
4
|
-
#
|
|
5
|
-
#
|
|
2
|
+
# Static reference named by update-context.md §9b, loaded only when
|
|
3
|
+
# manifest schema documentation is needed (skf-manifest-ops.py enforces
|
|
4
|
+
# the v2 shape and migrates v1 internally, so no step edits the manifest
|
|
5
|
+
# in the prompt).
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
<!-- Config: communicate in {communication_language}. -->
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
## Purpose
|
|
13
13
|
|
|
14
|
-
Reference for the v2 export manifest schema
|
|
14
|
+
Reference for the v2 export manifest schema that `skf-manifest-ops.py` enforces for every workflow that touches `{skills_output_folder}/.export-manifest.json`. This file documents the v2 shape and the helper implements it: export-skill, drop-skill and rename-skill read and edit manifest entries through the helper (`read`, `get`, `set`, `deprecate`, `remove`, `rename`), and `skf-rebuild-managed-sections.py assemble` reads it through the same code. Rename-skill's rollback is the one write outside it: it restores the byte copy of the manifest it kept before the re-key.
|
|
15
15
|
|
|
16
16
|
## v2 Schema
|
|
17
17
|
|
|
@@ -54,12 +54,11 @@ Reference for the v2 export manifest schema enforced by `skf-manifest-ops.py` an
|
|
|
54
54
|
|
|
55
55
|
Pre-rename v2 manifests used a `platforms` array at the version level. If a version entry contains `platforms` instead of (or in addition to) `ides`, the helper treats `platforms` as `ides` and rewrites it on the next manifest write — silent in-place upgrade, no user prompt.
|
|
56
56
|
|
|
57
|
-
For v1 manifests (no `schema_version` field), the
|
|
57
|
+
For v1 manifests (no `schema_version` field), every read returns the v2 shape, and the next write through the helper stores it:
|
|
58
58
|
|
|
59
|
-
1.
|
|
60
|
-
2.
|
|
61
|
-
3.
|
|
62
|
-
4. Set `schema_version: "2"` at root
|
|
59
|
+
1. Each entry's `versions` list becomes a map with one record per version: `ides: []` (unknown, filled on the next successful export) and `last_exported` from the manifest's `updated_at`
|
|
60
|
+
2. The entry's `active_version` keeps its value; that version's record gets `status: "active"`, or `"deprecated"` when the entry carries `deprecated: true`, and every other version `status: "archived"`
|
|
61
|
+
3. The `deprecated` and `deprecated_versions` keys are dropped and `schema_version: "2"` is set at the root
|
|
63
62
|
|
|
64
63
|
Workflows that load the manifest via `skf-manifest-ops.py read` receive a `{"status": "ok", "manifest": {...}}` envelope; the `manifest` value is always in canonical v2 shape regardless of on-disk state (parse `result["manifest"]`, not the top-level object).
|
|
65
64
|
|
|
@@ -23,15 +23,15 @@ Loaded by `load-skill.md` §1c when `len(skill_batch) > 1`.
|
|
|
23
23
|
| step 1 §2–5 | **Iterate per skill** — load, validate, read metadata, and check the test report for every skill in `skill_batch`. Collect per-skill results. |
|
|
24
24
|
| step 1 §6 | **Single gate** — present one consolidated summary table (one row per skill) and a single [C] gate for the whole batch. |
|
|
25
25
|
| step 2 | **Iterate per skill** — validate each skill's package structure and collect per-skill readiness. |
|
|
26
|
-
| step 3 | **Iterate per skill
|
|
27
|
-
| step 4 | **Batch once
|
|
26
|
+
| step 3 | **Iterate per skill**: regenerate each skill's `context-snippet.md` independently (each skill has its own prior-gotchas carry-forward state), staging and measuring each draft in the run's one stage folder. |
|
|
27
|
+
| step 4 | **Batch once**: §3b orphan detection, §4 section build, §5 to §9 check, preview, gate and write all run once for the entire batch. Each `assemble` call names every skill in `skill_batch` with `--include`, beside every skill of the manifest, so no batch member is left out, even on a first export. §9b records every skill in `skill_batch` with one `set` each, and §9c then writes each skill's snippet. |
|
|
28
28
|
| step 5 | **Iterate per skill** — compute token counts per skill, then present one aggregate report. |
|
|
29
|
-
| step 6 | **One batch summary + one result contract
|
|
29
|
+
| step 6 | **One batch summary + one result contract**: the files-written table lists every skill; the result contract JSON covers the whole run, and `outputs` enumerates every context-snippet, every target context file touched and the manifest. |
|
|
30
30
|
| step 7 | **Runs once** — health check is per-workflow-run, not per-skill. |
|
|
31
31
|
|
|
32
32
|
## Halt semantics
|
|
33
33
|
|
|
34
|
-
If any single skill fails validation in step 1 §2 (required-file or metadata-field failure), halt the entire batch before step 4
|
|
34
|
+
If any single skill fails validation in step 1 §2 (required-file or metadata-field failure) or is refused by the §2 ownership gate (`not-skf-output`: a flat skill SKF did not generate), halt the entire batch before step 4: do not partially export. Report which skill failed and why. The principle: a multi-skill run is a unit of work, not a per-skill best-effort sweep: partial exports leave the manifest and managed sections in an ambiguous state that's expensive for the operator to reconcile.
|
|
35
35
|
|
|
36
36
|
## Single-skill mode (reference)
|
|
37
37
|
|
|
@@ -37,13 +37,21 @@ Emit the warning and gate:
|
|
|
37
37
|
|
|
38
38
|
Wait for user choice.
|
|
39
39
|
|
|
40
|
-
**
|
|
40
|
+
**GATE [default: b]**, headless or non-interactive: when `{headless_mode}` (or dry-run, or unattended), default to **(b) keep** and print the warning only: no destructive action without explicit consent.
|
|
41
|
+
|
|
42
|
+
When `{headless_mode}` is true, also record the decision in the run sink, listing each orphaned file's `file_path` with `/` in place of `\` so it stays a JSON string. If `record` exits non-zero, display its error line and go on (a failed `record` never stops the run):
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
uv run {emitEnvelopeHelper} record --workflow skf-export-skill --run-dir "{run_dir}" --decision <<'SKF_JSON'
|
|
46
|
+
{"gate":"update-context.orphan-context-files","default_action":"b","taken_action":"b","reason":"headless: orphaned context files kept untouched","evidence":{"files":["{file_path}"]}}
|
|
47
|
+
SKF_JSON
|
|
48
|
+
```
|
|
41
49
|
|
|
42
50
|
## Choice handling
|
|
43
51
|
|
|
44
52
|
### (a) clear
|
|
45
53
|
|
|
46
|
-
The marker excision is deterministic surgery with one correct answer per input
|
|
54
|
+
The marker excision is deterministic surgery with one correct answer per input: a mis-parsed boundary silently corrupts the user's surrounding content. Delegate it to the tested `clear` action of `skf-rebuild-managed-sections.py`, the same helper `update-context.md` §9 writes the section with; do not excise markers in-prompt. `{rebuildManagedSectionsHelper}` is the path SKILL.md's On Activation resolved, and activation halts (exit code 4, `halt_reason: "context-rebuild-failed"`) when no candidate exists: falling through to an in-prompt excision would regress the atomic-write + post-clear verify guarantee.
|
|
47
55
|
|
|
48
56
|
For each file in `orphaned_context_files`:
|
|
49
57
|
|
|
@@ -62,7 +70,7 @@ Record nothing. The orphaned files remain on disk, untouched. Proceed.
|
|
|
62
70
|
|
|
63
71
|
### (c) rewrite
|
|
64
72
|
|
|
65
|
-
Add each entry in `orphaned_context_files` to a separate `rewrite_context_files` list. This list is kept distinct from `target_context_files` so the user's intent to only export to configured IDEs is preserved in the manifest update at §9b
|
|
73
|
+
Add each entry in `orphaned_context_files` to a separate `rewrite_context_files` list. This list is kept distinct from `target_context_files` so the user's intent to only export to configured IDEs is preserved in the manifest update at §9b: `rewrite_context_files` joins the §4 to §9 writes for this run only and is not promoted into the manifest's `ides` arrays.
|
|
66
74
|
|
|
67
75
|
Use `.agents/skills/` as the default skill root for rewritten orphans (the IDE-neutral path used when the original IDE mapping is no longer available).
|
|
68
76
|
|
|
@@ -74,9 +82,9 @@ After this protocol completes, §3b returns control to §4 with these workflow-c
|
|
|
74
82
|
|
|
75
83
|
- `orphans_cleared: []` — set when the user chose (a) or stayed empty otherwise
|
|
76
84
|
- `orphans_rewritten: []` — set when the user chose (c) or stayed empty otherwise
|
|
77
|
-
- `rewrite_context_files: []
|
|
85
|
+
- `rewrite_context_files: []`: joins the targets of §4 to §9 when the user chose (c)
|
|
78
86
|
|
|
79
|
-
|
|
87
|
+
§4 to §9 run over `target_context_files + rewrite_context_files`. The §9b manifest update reads only `target_context_files` (rewritten orphans are not promoted into the manifest).
|
|
80
88
|
|
|
81
89
|
## Scope note
|
|
82
90
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
# Static reference loaded by update-context.md §4c.1 only when
|
|
3
|
-
# `
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
#
|
|
3
|
+
# `orphan_rows` is non-empty (the §4b `assemble` results list
|
|
4
|
+
# `[skill-name v...]` rows of the current managed sections whose skill
|
|
5
|
+
# neither the export manifest nor this run's batch holds). The
|
|
6
|
+
# reference carries the (a)/(b)/(c) gate protocol, headless default,
|
|
7
|
+
# deviations[] contract, and step 6 result-contract integration; the
|
|
8
|
+
# trigger itself stays inline in §4c.1 so the LLM knows when to invoke
|
|
9
|
+
# this protocol.
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
<!-- Config: communicate in {communication_language}. Render the orphan list and gate prompt in {document_output_language}. -->
|
|
@@ -15,13 +15,13 @@
|
|
|
15
15
|
|
|
16
16
|
## Purpose
|
|
17
17
|
|
|
18
|
-
Handle the (a) Drop / (b) Preserve verbatim / (c) Cancel gate when the
|
|
18
|
+
Handle the (a) Drop / (b) Preserve verbatim / (c) Cancel gate when the managed section of a target context file holds `[skill-name v...]` rows for skills that neither the export manifest nor this run's batch holds: typically externally-installed skills authored in a different repo and dropped into `{skills_output_folder}` without going through export-skill.
|
|
19
19
|
|
|
20
20
|
Strict ADR-K would silently drop such rows, but the user's managed section is load-bearing — silent removal of an installed skill is a regression. The convention captured in `skills/export-skill-result-latest.json` deviations is to make this an explicit operator (or `{headless_mode}`) choice.
|
|
21
21
|
|
|
22
22
|
## Inputs
|
|
23
23
|
|
|
24
|
-
- `
|
|
24
|
+
- `orphan_rows`: the `{skill_name, version, snippet_text, source_files: [], skill_type}` entries `assemble` returned in §4b, found across **every** target context file and deduplicated by `(skill_name, version)`. `source_files` carries the file paths the orphan appeared in (one entry per file in which the row was found). `snippet_text` is the original row captured verbatim from the first file that holds it, which (b) writes back unchanged.
|
|
25
25
|
- `target_context_files` — the full IDE → context-file list (referenced in the gate's framing copy so the user understands the consolidation scope)
|
|
26
26
|
- `{headless_mode}` — boolean flag from workflow context
|
|
27
27
|
|
|
@@ -33,17 +33,25 @@ Emit the gate:
|
|
|
33
33
|
>
|
|
34
34
|
> {list each as `- {skill_name} v{version} (in: {comma-separated source_files})`}
|
|
35
35
|
>
|
|
36
|
-
> These skills appear in one or more existing managed sections but
|
|
36
|
+
> These skills appear in one or more existing managed sections, but `.export-manifest.json` has no entry for them and this export does not include them. They were likely installed from a different repo and never run through export-skill in this project. Options:
|
|
37
37
|
>
|
|
38
38
|
> - **(a) Drop** — remove these rows from the rebuilt managed section across **all** target context files (strict ADR-K behavior). The skills' on-disk files are not touched, but they will no longer appear in any context file's managed index.
|
|
39
39
|
> - **(b) Preserve verbatim** — copy each orphan's existing snippet line(s) into the rebuilt managed section across **all** target context files unchanged (one canonical row per `(skill, version)` written everywhere — orphans become symmetric across IDEs as a side effect, which is the correct outcome since the user's intent is "these external skills should appear in my managed index"). Records `deviations[].kind = "preserve_external_skills"` with the affected skill names, versions, and `source_files` in the result contract for audit.
|
|
40
|
-
> - **(c) Cancel** — abort export.
|
|
40
|
+
> - **(c) Cancel** — abort export. Before re-running, run export-skill on each of these skills that SKF generated (its `metadata.json` carries an SKF marker) to add it to the manifest, and remove the rows of the other skills from the context files yourself.
|
|
41
41
|
|
|
42
42
|
Wait for user choice.
|
|
43
43
|
|
|
44
|
-
**
|
|
44
|
+
**GATE [default: b]** (when `{headless_mode}`): auto-select **(b) Preserve verbatim**, with the same `deviations[]` entry. Emit a loud log line:
|
|
45
45
|
|
|
46
|
-
> `headless: {N} managed-section rows had no manifest entry; preserving verbatim with deviations[].kind = preserve_external_skills. Run export-skill
|
|
46
|
+
> `headless: {N} managed-section rows had no manifest entry; preserving verbatim with deviations[].kind = preserve_external_skills. Run export-skill on each skill SKF generated to add it to the manifest; remove the rows of other skills from the context files yourself.`
|
|
47
|
+
|
|
48
|
+
Record the decision in the run sink, listing each orphan row as `{skill_name} v{version}`. If `record` exits non-zero, display its error line and go on (a failed `record` never stops the run):
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
uv run {emitEnvelopeHelper} record --workflow skf-export-skill --run-dir "{run_dir}" --decision <<'SKF_JSON'
|
|
52
|
+
{"gate":"update-context.orphan-rows","default_action":"b","taken_action":"b","reason":"headless: managed-section rows with no manifest entry preserved verbatim","evidence":{"rows":["{skill_name} v{version}"]}}
|
|
53
|
+
SKF_JSON
|
|
54
|
+
```
|
|
47
55
|
|
|
48
56
|
Silent drop under automation would regress the user's managed section without consent; cancel under automation would block the whole export over an externally-installed skill the user did not author. Preservation matches the prior-attentive-operator convention.
|
|
49
57
|
|
|
@@ -51,19 +59,19 @@ Silent drop under automation would regress the user's managed section without co
|
|
|
51
59
|
|
|
52
60
|
### (a) Drop
|
|
53
61
|
|
|
54
|
-
|
|
62
|
+
Run update-context.md §4b again for every target with `--orphans drop`, so no rebuilt section holds an orphan row. Record:
|
|
55
63
|
|
|
56
64
|
```
|
|
57
65
|
orphans_dropped = [{skill_name, version}, …]
|
|
58
66
|
```
|
|
59
67
|
|
|
60
|
-
in workflow context for the
|
|
68
|
+
in workflow context for the step 6 result contract.
|
|
61
69
|
|
|
62
70
|
### (b) Preserve verbatim
|
|
63
71
|
|
|
64
|
-
|
|
72
|
+
Keep the bodies §4b staged: `assemble` already wrote each orphan's `snippet_text` into them verbatim, sorted with the other rows by skill name, **once** per section, and counted it as a stack skill when its row has a `|stack:` line. Nothing is merged by hand.
|
|
65
73
|
|
|
66
|
-
Append the following entry to the `deviations[]` array in the
|
|
74
|
+
Append the following entry to the `deviations[]` array in the step 6 result contract:
|
|
67
75
|
|
|
68
76
|
```json
|
|
69
77
|
{
|
|
@@ -77,7 +85,7 @@ Append the following entry to the `deviations[]` array in the §6 result contrac
|
|
|
77
85
|
|
|
78
86
|
`source_files` per skill records the prior context files the orphan was found in (asymmetric provenance preserved for audit) — useful when an operator later debugs which IDE's managed section originally carried the row.
|
|
79
87
|
|
|
80
|
-
|
|
88
|
+
Every §4b call scans every target file in the same order, so the same orphans are written to **every** target context file: all configured IDEs end up with consistent managed sections (asymmetric prior orphans become symmetric, the correct outcome for the "preserve external skills" intent).
|
|
81
89
|
|
|
82
90
|
### (c) Cancel
|
|
83
91
|
|
|
@@ -86,17 +94,18 @@ HALT the workflow:
|
|
|
86
94
|
- Do not rewrite any context file.
|
|
87
95
|
- Do not update the manifest.
|
|
88
96
|
- Do not produce a result contract.
|
|
97
|
+
- Delete the `{export_stage_dir}` folder, as every exit from update-context.md does.
|
|
89
98
|
- Exit code 6, `halt_reason: "user-cancelled"` (matches the §8 Menu cancel semantics).
|
|
90
99
|
- In headless mode this branch is never taken (headless default is (b)), so this exit path is interactive-only.
|
|
91
100
|
|
|
92
101
|
## Downstream contract
|
|
93
102
|
|
|
94
|
-
After this protocol completes, §4c.1 returns control to §
|
|
103
|
+
After this protocol completes, §4c.1 returns control to §5 with these workflow-context variables populated:
|
|
95
104
|
|
|
96
|
-
- `orphans_dropped: []
|
|
105
|
+
- `orphans_dropped: []`: set when the user chose (a), else empty
|
|
97
106
|
- `deviations[]` — extended with the `preserve_external_skills` entry when the user chose (b)
|
|
98
|
-
- The
|
|
107
|
+
- The staged bodies hold the orphan rows verbatim when (b) was chosen, and leave them out when (a) was chosen
|
|
99
108
|
|
|
100
109
|
## Scope note
|
|
101
110
|
|
|
102
|
-
This
|
|
111
|
+
This gate runs once per export run, not per target context file: every §4b call passes every target file as `--orphan-sources`, so each result lists the same orphans, deduplicated by `(skill_name, version)`. The gate's choice applies globally, and asymmetric orphans (a row present in `.cursorrules` but not in `CLAUDE.md`, or vice versa) are detected and surfaced with `source_files` provenance.
|
|
@@ -1,98 +1,40 @@
|
|
|
1
1
|
---
|
|
2
2
|
nextStepFile: 'generate-snippet.md'
|
|
3
|
-
# `{validateOutputHelper}` resolves from `{validateOutputProbeOrder}` (first
|
|
4
|
-
# existing path wins). Step 1 §2 already ran `--export-gate` and retained the
|
|
5
|
-
# JSON verdict; this step renders its status from that verdict. Only re-run the
|
|
6
|
-
# command below if the step-1 JSON is not in context (e.g. package.md entered
|
|
7
|
-
# directly). The verdict is deterministic — same package → same result.
|
|
8
|
-
validateOutputProbeOrder:
|
|
9
|
-
- '{project-root}/_bmad/skf/shared/scripts/skf-validate-output.py'
|
|
10
|
-
- '{project-root}/src/shared/scripts/skf-validate-output.py'
|
|
11
3
|
---
|
|
12
4
|
|
|
13
|
-
<!-- Config: communicate in {communication_language}.
|
|
5
|
+
<!-- Config: communicate in {communication_language}. Render the package status in {document_output_language}. -->
|
|
14
6
|
|
|
15
7
|
# Step 2: Package
|
|
16
8
|
|
|
17
9
|
## STEP GOAL:
|
|
18
10
|
|
|
19
|
-
To
|
|
11
|
+
To report each skill's package status from the export-gate verdict step 1 §2 retained, without checking the package again.
|
|
20
12
|
|
|
21
13
|
## Rules
|
|
22
14
|
|
|
23
|
-
-
|
|
15
|
+
- Read the verdict, never re-derive a check it covers, and never modify the package
|
|
24
16
|
- Auto-proceed when complete
|
|
25
|
-
- **Multi-skill mode:** when step 1 loaded more than one skill (`len(skill_batch) > 1`),
|
|
17
|
+
- **Multi-skill mode:** when step 1 loaded more than one skill (`len(skill_batch) > 1`), report one row per skill, each from its own verdict. See step 1 §1c.
|
|
26
18
|
|
|
27
19
|
## MANDATORY SEQUENCE
|
|
28
20
|
|
|
29
|
-
### 1.
|
|
21
|
+
### 1. Read the Verdict
|
|
30
22
|
|
|
31
|
-
|
|
23
|
+
Use the export-gate JSON step 1 §2 retained for `{resolved_skill_package}`. Only when it is not in context, run `python3 {validateOutputHelper} {resolved_skill_package} --export-gate` again: the same package gives the same verdict. Step 1 §2 halts on `NOT_READY`, so `export_status` is `READY` or `WARNINGS` here.
|
|
32
24
|
|
|
33
|
-
|
|
34
|
-
{skill_package} = {skills_output_folder}/{skill-name}/{version}/{skill-name}/
|
|
35
|
-
├── SKILL.md ← Required: Active skill document
|
|
36
|
-
├── metadata.json ← Required: Machine-readable metadata
|
|
37
|
-
├── context-snippet.md ← Will be generated/updated in step 3
|
|
38
|
-
├── references/ ← Optional: Progressive disclosure
|
|
39
|
-
│ ├── {function-a}.md
|
|
40
|
-
│ └── {function-b}.md
|
|
41
|
-
├── scripts/ ← Optional: Executable automation
|
|
42
|
-
└── assets/ ← Optional: Templates, schemas, configs
|
|
43
|
-
```
|
|
25
|
+
### 2. Report Package Status
|
|
44
26
|
|
|
45
|
-
**
|
|
27
|
+
"**Package checked.**
|
|
46
28
|
|
|
47
|
-
|
|
29
|
+
**Status:** {export_status}
|
|
30
|
+
**references/:** {the count of `.md` files under `{resolved_skill_package}/references/`, or none}
|
|
48
31
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
-
|
|
52
|
-
- SKILL.md Section 7b ↔ on-disk `scripts/`/`assets/` cross-reference — `validation.crossref_7b.missing` (high: §7b-named file absent on disk) and `validation.crossref_7b.orphans` (low: on-disk file not referenced in §7b)
|
|
32
|
+
{If export_status is WARNINGS:}
|
|
33
|
+
**Warnings** (none of them stops the export):
|
|
34
|
+
- {the `field` of each `validation.metadata.recommended_missing` entry, each path in `validation.crossref_7b.orphans`, and the message of each low issue in `validation.metadata.issues`, such as an empty `exports` array or a forge tier in an older stack's `confidence_tier`}"
|
|
53
35
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
### 2. Validate Metadata Completeness
|
|
57
|
-
|
|
58
|
-
Check metadata.json for recommended (non-required) fields:
|
|
59
|
-
|
|
60
|
-
- `description` — Brief skill description
|
|
61
|
-
- `source_repo` — Source repository URL
|
|
62
|
-
- `language` — Primary language of source code
|
|
63
|
-
- `ast_node_count` — Number of AST nodes analyzed
|
|
64
|
-
- `tool_versions` — Tools used during generation
|
|
65
|
-
|
|
66
|
-
**For each missing recommended field:** Note as warning, do not halt.
|
|
67
|
-
|
|
68
|
-
### 3. Assess Package Readiness
|
|
69
|
-
|
|
70
|
-
Read `export_status` directly from the export-gate verdict (step 1 §2) — do not re-compute the status by hand:
|
|
71
|
-
|
|
72
|
-
- **READY** — the verdict has no issues (`export_status: "READY"`).
|
|
73
|
-
- **WARNINGS** — only medium/low issues remain (`export_status: "WARNINGS"`): §7b orphans, an empty `exports` array, or the recommended-field notes from §2 above.
|
|
74
|
-
- **NOT READY** — any high-severity issue (`export_status: "NOT_READY"`). Step 1 §2 halts on this, so a healthy run never reaches here; if it does, surface the high-severity messages and halt.
|
|
75
|
-
|
|
76
|
-
### 4. Report Package Status
|
|
77
|
-
|
|
78
|
-
"**Package structure validated.**
|
|
79
|
-
|
|
80
|
-
**Status:** {export_status: READY / WARNINGS}
|
|
81
|
-
|
|
82
|
-
**Required Components:**
|
|
83
|
-
- SKILL.md: ✅
|
|
84
|
-
- metadata.json: ✅ (required fields valid per export-gate verdict)
|
|
85
|
-
- references/: {✅ present ({count} files) / ⚠️ not present}
|
|
86
|
-
|
|
87
|
-
{If warnings (export_status: WARNINGS):}
|
|
88
|
-
**Warnings:**
|
|
89
|
-
- {list missing recommended fields from §2, plus any `validation.crossref_7b.orphans` and an empty `exports` warning from the verdict}
|
|
90
|
-
|
|
91
|
-
**Package is ready for snippet generation.**"
|
|
92
|
-
|
|
93
|
-
### 5. Proceed to Snippet Generation
|
|
36
|
+
### 3. Proceed to Snippet Generation
|
|
94
37
|
|
|
95
38
|
Display: "**Proceeding to snippet generation...**"
|
|
96
39
|
|
|
97
|
-
Auto-proceed (no user choices):
|
|
98
|
-
|
|
40
|
+
Auto-proceed (no user choices): load, read entirely, and execute `{nextStepFile}`.
|
|
@@ -1,98 +1,79 @@
|
|
|
1
1
|
---
|
|
2
|
-
#
|
|
3
|
-
# `snippet_skill_root_override
|
|
4
|
-
# override is set, every existing snippet's on-disk prefix is ground
|
|
5
|
-
# truth by contract — no probe needed and the entire authoring-repo
|
|
6
|
-
# escape hatch is already configured. Loaded once per export run, not
|
|
7
|
-
# per skill.
|
|
8
|
-
# Resolve `{rebuildManagedSectionsHelper}` by probing
|
|
9
|
-
# `{rebuildManagedSectionsProbeOrder}` in order (installed SKF module
|
|
10
|
-
# path first, src/ dev-checkout fallback); first existing path wins.
|
|
11
|
-
# The `root-probe` action reads each candidate snippet's first line,
|
|
12
|
-
# parses/strips the `root:` prefix, and returns `observed_prefixes` +
|
|
13
|
-
# `mismatch` — deterministic prefix comparison the LLM must not re-derive.
|
|
14
|
-
rebuildManagedSectionsProbeOrder:
|
|
15
|
-
- '{project-root}/_bmad/skf/shared/scripts/skf-rebuild-managed-sections.py'
|
|
16
|
-
- '{project-root}/src/shared/scripts/skf-rebuild-managed-sections.py'
|
|
2
|
+
# Loaded by load-skill.md §1b, once per run, only when config.yaml sets no
|
|
3
|
+
# `snippet_skill_root_override`.
|
|
17
4
|
---
|
|
18
5
|
|
|
19
|
-
<!-- Config: communicate in {communication_language}. Render the warning and gate prompt in {document_output_language}. -->
|
|
6
|
+
<!-- Config: communicate in {communication_language}. Render the question, the warning and the gate prompt in {document_output_language}. -->
|
|
20
7
|
|
|
21
|
-
# Snippet Root
|
|
8
|
+
# Snippet Root Probe
|
|
22
9
|
|
|
23
10
|
## Purpose
|
|
24
11
|
|
|
25
|
-
|
|
12
|
+
Decide where the managed section points each skill before step 3 writes a `root:` path. A consuming project points at its IDE's skill folder (`.claude/skills/`, `.cursor/skills/` and so on), where `npx skills add` installs each skill. An authoring repo keeps its skills in one shared folder, such as `skills/`, and sets `snippet_skill_root_override` in `config.yaml`. Only a root an earlier export chose shows the layout: create-skill, create-stack-skill, quick-skill and update-skill write the draft root `skills/{skill-name}/` into every snippet they build, whatever the layout. So a repo whose skills live in `skills/` sets `snippet_skill_root_override: skills/`: a `skills/{skill-name}/` root an earlier export wrote reads as a draft root, and without the override the probe asks the Layout Question, whose headless default is the IDE skill folder.
|
|
26
13
|
|
|
27
|
-
|
|
14
|
+
`{reference_root}` is `target_context_files[0].skill_root`, the root step 3 writes when nothing overrides it.
|
|
28
15
|
|
|
29
|
-
##
|
|
16
|
+
## Probe
|
|
30
17
|
|
|
31
|
-
|
|
32
|
-
- `{skills_output_folder}` — for manifest-driven candidate enumeration
|
|
33
|
-
- Current skill's snippet path (resolved via manifest / `active` symlink / flat path per `knowledge/version-paths.md`)
|
|
34
|
-
- `{headless_mode}` — boolean flag from workflow context
|
|
18
|
+
List the snippet of each version the export manifest records: for each skill in step 1 §1's `result.manifest.exports` whose `active_version` has an entry under `versions`, `{skills_output_folder}/{skill-name}/{active_version}/{skill-name}/context-snippet.md`. A skill the manifest does not list was never exported, so its snippet holds the draft root only. With no snippet to list, go to the Layout Question. Otherwise run:
|
|
35
19
|
|
|
36
|
-
|
|
20
|
+
```bash
|
|
21
|
+
python3 {rebuildManagedSectionsHelper} root-probe {snippet-1} {snippet-2} … --reference-root "{reference_root}" --project-root "{project-root}"
|
|
22
|
+
```
|
|
37
23
|
|
|
38
|
-
|
|
39
|
-
- Read `{skills_output_folder}/.export-manifest.json` if it exists. For each skill in `exports` with a resolvable `active_version`, add `{skills_output_folder}/{skill-name}/{active_version}/{skill-name}/context-snippet.md`.
|
|
40
|
-
- Also include the current skill's snippet if present.
|
|
41
|
-
2. **Read the prefixes and compare via the helper** — reading each snippet's first line, parsing/stripping the `root:` prefix, collecting the unique set, and comparing against the reference is deterministic prefix arithmetic with one correct answer per input. Resolve `{rebuildManagedSectionsHelper}` from `{rebuildManagedSectionsProbeOrder}` (frontmatter — first existing path wins; if no candidate exists, skip the probe and continue to §2 without a warning rather than blocking export on a missing dev-only helper), then run:
|
|
24
|
+
The helper reads each snippet's `root:` prefix and leaves out a snippet that is missing, has no root, or holds the draft root (it lists those skills in `draft_roots`). It returns `observed_prefixes`, `mismatch` (true when one of them is not `{reference_root}`), `mismatched_skills`, and `disk_root`: `{reference_root}` when that folder holds every mismatched skill, else the one observed prefix when that folder holds them all, else null. Then:
|
|
42
25
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
26
|
+
- `observed_prefixes` is empty: no earlier export chose a root. Ask the Layout Question.
|
|
27
|
+
- `mismatch` is false: every earlier export chose `{reference_root}`. Ask nothing and return to load-skill.md §1b.
|
|
28
|
+
- `mismatch` is true: take the Mismatch Gate.
|
|
46
29
|
|
|
47
|
-
|
|
30
|
+
## Layout Question
|
|
48
31
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
32
|
+
> **Where should the managed section point your skills?** No earlier export has chosen yet. By default each row points at `{reference_root}{skill-name}/`, your IDE's skill folder, where `npx skills add` installs the skill (step 6 prints the command).
|
|
33
|
+
>
|
|
34
|
+
> - **[I] IDE skill folder** (default): point at `{reference_root}`.
|
|
35
|
+
> - **[S] Shared skills folder**: point at the skills where SKF writes them, for a repo that keeps them there. Export, drop-skill and rename-skill read that choice from `config.yaml`.
|
|
36
|
+
> - **[X] Cancel**
|
|
52
37
|
|
|
53
|
-
|
|
38
|
+
Wait for the user's choice.
|
|
54
39
|
|
|
55
|
-
|
|
40
|
+
- **[I]**: return to load-skill.md §1b.
|
|
41
|
+
- **[S]**: display "Add `snippet_skill_root_override: {skills_prefix}` to `{project-root}/_bmad/skf/config.yaml`, then re-run the export." and HALT (exit code 6, `halt_reason: "user-cancelled"`): the workflow never edits `config.yaml`. `{skills_prefix}` is the path of `{skills_output_folder}` from `{project-root}`, with a trailing `/`, such as `skills/`.
|
|
42
|
+
- **[X]** / `cancel` / `exit` / `:q`: HALT (exit code 6, `halt_reason: "user-cancelled"`). Nothing was written.
|
|
43
|
+
- **GATE [default: I]**: headless, record the decision in the run sink with the command below, log "headless: no earlier export chose a snippet root, using the IDE skill folder", then take [I]. If `record` exits non-zero, display its error line and go on: a failed `record` never stops the run.
|
|
56
44
|
|
|
57
|
-
|
|
45
|
+
```bash
|
|
46
|
+
uv run {emitEnvelopeHelper} record --workflow skf-export-skill --run-dir "{run_dir}" --decision <<'SKF_JSON'
|
|
47
|
+
{"gate":"load-skill.snippet-root-layout","default_action":"I","taken_action":"I","reason":"headless: no earlier export chose a snippet root, using the IDE skill folder","evidence":{"reference_root":"{reference_root}"}}
|
|
48
|
+
SKF_JSON
|
|
49
|
+
```
|
|
58
50
|
|
|
59
|
-
|
|
51
|
+
## Mismatch Gate
|
|
60
52
|
|
|
61
53
|
> **Snippet root prefix mismatch detected.**
|
|
62
|
-
>
|
|
63
|
-
> IDE
|
|
54
|
+
> Earlier exports point at: `{observed_prefixes}`
|
|
55
|
+
> The IDE mapping points at: `{reference_root}`
|
|
64
56
|
>
|
|
65
|
-
>
|
|
57
|
+
> - **(a) Set override**: add `snippet_skill_root_override: {observed_prefix}` to `config.yaml`, which export, drop-skill and rename-skill all read. Snippets keep their on-disk prefix.
|
|
58
|
+
> - **(b) Proceed with IDE mapping**: every row's root becomes `{reference_root}`. Use this when that folder holds the skills, or will once you install them there.
|
|
59
|
+
> - **(c) Cancel**: abort the export and investigate.
|
|
60
|
+
> - **(d) Use the observed prefix for this run only**: every row's root stays `{observed_prefix}`, and `config.yaml` is not changed. (Offered only when exactly one prefix was observed.)
|
|
66
61
|
>
|
|
67
|
-
>
|
|
68
|
-
> - **(b) Proceed with IDE mapping** — step 4 will rewrite every snippet's root path to the IDE's skill_root. Use this only if the IDE's skill directory actually contains the skill files.
|
|
69
|
-
> - **(c) Cancel** — abort export and investigate.
|
|
70
|
-
> - **(d) Use observed prefix for this run only** — set the effective snippet root to the single observed on-disk prefix for this export run, without writing to `config.yaml`. The managed section references the real on-disk location. (Only offered when exactly one prefix was observed.)
|
|
71
|
-
>
|
|
72
|
-
> If multiple distinct prefixes were observed, the snippets disagree with each other — investigate before choosing (a) or (d).
|
|
73
|
-
|
|
74
|
-
Wait for user choice.
|
|
75
|
-
|
|
76
|
-
**Headless default:** when `{headless_mode}`, default to **(b) Proceed with IDE mapping** and log the observed prefix(es) so the mismatch is visible in run logs (not silent).
|
|
77
|
-
|
|
78
|
-
## Choice handling
|
|
79
|
-
|
|
80
|
-
### (a) Set override
|
|
81
|
-
|
|
82
|
-
Halt and instruct the user to update `config.yaml` with `snippet_skill_root_override: {observed_prefix}`, then re-run export. Exit code 6, `halt_reason: "user-cancelled"` (configuration change is out-of-band — workflow does not edit config.yaml on the user's behalf).
|
|
83
|
-
|
|
84
|
-
### (b) Proceed with IDE mapping
|
|
85
|
-
|
|
86
|
-
Continue to §2. Step 4's root-rewrite algorithm will rewrite every snippet's prefix to the reference `skill_root`. The user is accepting that the IDE's skill directory contains the actual files; if it does not, the resulting managed section will reference paths that don't resolve.
|
|
87
|
-
|
|
88
|
-
### (c) Cancel
|
|
62
|
+
> If several prefixes were observed, the snippets disagree with each other: investigate before choosing (a).
|
|
89
63
|
|
|
90
|
-
|
|
64
|
+
Wait for the user's choice.
|
|
91
65
|
|
|
92
|
-
|
|
66
|
+
**GATE [default: (d) or (b), by the disk]**: headless, take (d) when `disk_root` is the observed prefix (that folder holds the skills and `{reference_root}` does not), else (b): `{reference_root}` holds them, or no folder does yet, as in a project that installs its skills after the export. `{choice}` is the option taken. Log it with the observed prefixes, record the decision in the run sink with the command below (`{disk_root}` is `none` when it is null), then take that option. If `record` exits non-zero, display its error line and go on: a failed `record` never stops the run.
|
|
93
67
|
|
|
94
|
-
|
|
68
|
+
```bash
|
|
69
|
+
uv run {emitEnvelopeHelper} record --workflow skf-export-skill --run-dir "{run_dir}" --decision <<'SKF_JSON'
|
|
70
|
+
{"gate":"load-skill.snippet-root-probe","default_action":"{choice}","taken_action":"{choice}","reason":"headless: snippet root prefix mismatch, option {choice} by the folder on disk that holds the skills","evidence":{"observed_prefixes":{observed_prefixes},"reference_root":"{reference_root}","disk_root":"{disk_root}"}}
|
|
71
|
+
SKF_JSON
|
|
72
|
+
```
|
|
95
73
|
|
|
96
|
-
|
|
74
|
+
### Choice handling
|
|
97
75
|
|
|
98
|
-
**
|
|
76
|
+
- **(a) Set override**: display "Add `snippet_skill_root_override: {observed_prefix}` to `{project-root}/_bmad/skf/config.yaml`, then re-run the export." and HALT (exit code 6, `halt_reason: "user-cancelled"`): the workflow never edits `config.yaml`.
|
|
77
|
+
- **(b) Proceed with IDE mapping**: return to load-skill.md §1b. Step 4 writes `{reference_root}` as every row's root.
|
|
78
|
+
- **(c) Cancel**: HALT (exit code 6, `halt_reason: "user-cancelled"`). Nothing was written.
|
|
79
|
+
- **(d) Use the observed prefix for this run only**: bind `{snippet_skill_root_override}` ← the observed prefix for this run, without editing `config.yaml`. Step 3 §2.7 and step 4 §4b read it as they read the `config.yaml` value, so every snippet and row keeps that root. Display "Persist `snippet_skill_root_override: {observed_prefix}` in `{project-root}/_bmad/skf/config.yaml` to skip this question next time: drop-skill and rename-skill read only `config.yaml` when they rebuild the section." Return to load-skill.md §1b.
|
|
@@ -1,28 +1,43 @@
|
|
|
1
|
-
<!-- Config:
|
|
1
|
+
<!-- Config: a machine-parsed contract. The shared emitter builds every line; never type one. -->
|
|
2
2
|
|
|
3
3
|
# Headless Result Envelope
|
|
4
4
|
|
|
5
|
-
The single-line
|
|
5
|
+
The single-line `SKF_EXPORT_RESULT_JSON: {…}` envelope export-skill emits on non-interactive (`{headless_mode}`) runs. Pipeline consumers parse it to branch on the run's outcome; `shared/scripts/schemas/skf-export-result-envelope.v1.json` describes each field. The shared emitter builds every line from the payload the run passes it on stdin, checks it against that schema and prints it.
|
|
6
|
+
|
|
7
|
+
`{emitEnvelopeHelper}` is the emitter SKILL.md's On Activation resolved: the first existing path of `{project-root}/_bmad/skf/shared/scripts/skf-emit-result-envelope.py` and `{project-root}/src/shared/scripts/skf-emit-result-envelope.py`. `{run_dir}` is the run folder a headless run created under `{project-root}/_bmad-output/.skf-run/`: its sink holds the auto-decision each gate recorded, which the emitter folds into every line as `headless_decisions`.
|
|
6
8
|
|
|
7
9
|
## Emission rule
|
|
8
10
|
|
|
9
|
-
- **Success / dry-run:** step 6 (`summary.md`)
|
|
10
|
-
- **Every HARD HALT
|
|
11
|
+
- **Success / dry-run:** step 6 (`summary.md` §6) runs `emit` once, on **stdout**, before chaining to step 7.
|
|
12
|
+
- **Every HARD HALT** of a headless run: run `emit-halt` as below, which prints the line on **stderr** with `status: "error"`, then exit with the halt's code (Exit Codes below). An interactive halt displays its message only.
|
|
11
13
|
|
|
12
|
-
##
|
|
14
|
+
## Emitting a Halt
|
|
13
15
|
|
|
16
|
+
Each HARD HALT a headless run can reach names its exit code, its `halt_reason` and its phase in the step files; every other field follows the run's state as below. Pass the halt's payload in a quoted heredoc, so no value is expanded. Each value is a JSON string: write a path with `/` in place of `\`, and a quote inside the message as a backtick.
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
uv run {emitEnvelopeHelper} emit-halt --workflow skf-export-skill [--run-dir "{run_dir}"] --target stderr <<'SKF_JSON'
|
|
20
|
+
{"phase":"<phase>","reason":"<the halt message>","halt_reason":"<halt_reason>","skills":["<name>"]}
|
|
21
|
+
SKF_JSON
|
|
14
22
|
```
|
|
15
|
-
SKF_EXPORT_RESULT_JSON: {"status":"success|error|dry-run","skills":[],"context_files_updated":[],"manifest_path":"…|null","headless_decisions":[],"exit_code":0,"halt_reason":null}
|
|
16
|
-
```
|
|
17
23
|
|
|
18
|
-
|
|
24
|
+
- `phase` is the phase the halt site names, `<step file> §<section>` (for example `update-context §9`), and `reason` is the message the halt displays, on one line.
|
|
25
|
+
- `halt_reason` is the value the halt site names. The emitter derives `exit_code` from it and sets `status: "error"`; leave both out.
|
|
26
|
+
- Always pass `skills`, the resolved batch (`[]` only before step 1 bound `skill_batch`, as at every On Activation halt).
|
|
27
|
+
- Add `context_files_updated`, the context files step 4 §9 wrote before the halt, once it has written one, and `manifest_path`, the `{manifest_path}` step 4 §9b bound, once the manifest is written. Before that, leave each out: the emitter gives `context_files_updated` `[]` and `manifest_path` `null`.
|
|
28
|
+
- Pass `--run-dir` once On Activation bound `{run_dir}`, so the line carries the decisions taken before the halt. A halt writes no result file.
|
|
29
|
+
|
|
30
|
+
Display the line the emitter prints. If it exits non-zero or prints no line, display the halt reason alone.
|
|
31
|
+
|
|
32
|
+
## Exit Codes
|
|
19
33
|
|
|
20
|
-
|
|
21
|
-
- `skills` — resolved skill names in the batch (JSON array).
|
|
22
|
-
- `context_files_updated` — context files successfully written this run (JSON array; `[]` when a HALT preceded any write).
|
|
23
|
-
- `manifest_path` — the written manifest path, or `null` when no manifest write completed.
|
|
24
|
-
- `headless_decisions` — the `{gate, default_action, taken_action, reason}` entries logged as each gate auto-resolved (JSON array).
|
|
25
|
-
- `exit_code` — 0 success/dry-run · 2 input-missing · 3 resolution-failure · 4 write-failure · 5 state-conflict · 6 user-cancelled.
|
|
26
|
-
- `halt_reason` — `null` on success/dry-run, else one of: `"input-missing"`, `"resolution-failure"`, `"malformed-markers"`, `"manifest-write-failed"`, `"context-rebuild-failed"`, `"write-failed"`, `"user-cancelled"`. Each value is emitted by a real HALT site (see the SKILL.md Exit Codes table for the code↔reason map); the enum lists no value that no stage emits.
|
|
34
|
+
Every HARD HALT exits with a stable code, so headless automators can branch on the failure class without grepping message text:
|
|
27
35
|
|
|
28
|
-
|
|
36
|
+
| Code | Meaning | Raised by (halt site → `halt_reason`) |
|
|
37
|
+
| ---- | -------------------- | -------------------------------------------------------------------------------------------- |
|
|
38
|
+
| 0 | success | step 7 (terminal); also `status="dry-run"` when `--dry-run` is set |
|
|
39
|
+
| 2 | input-missing | step 1 §1: a headless run with no `skill_name` and no `--all` (a non-interactive run cannot answer the skill-selection menu) → `input-missing` |
|
|
40
|
+
| 3 | resolution-failure | step 1 §1 (discovery finds no skills on disk / in the manifest; the export manifest does not parse; context-file resolution refuses an unknown `--context-file` value or cannot read the IDE mapping); step 1 §2 (the inventory helper finds no version of a named skill to export, or its required artifacts are missing or its metadata is invalid: export-gate FAIL); multi-skill batch (any skill failing §2 validation halts the whole batch) → `resolution-failure`; step 1 §2 flat fallback (a flat `SKILL.md` with no SKF marker in its `metadata.json`, so SKF will not migrate or export it) → `not-skf-output` |
|
|
41
|
+
| 4 | write-failure | On-Activation §4 (the run folder cannot be created) or §5 pre-flight write check, or step 4 §9c (a snippet write fails) → `write-failed`; On-Activation §4 (a required helper is missing), step 3 §4 (the token counter fails), step 4 §3b (an orphaned file's clear fails), §4b (the body cannot be built, for example a context file that is not UTF-8 text) or §9 (a write fails its check) → `context-rebuild-failed`; step 4 §9b manifest write → `manifest-write-failed` |
|
|
42
|
+
| 5 | state-conflict | step 4 §4b or §5: `check` finds a `<!-- SKF:BEGIN` marker that no `<!-- SKF:END -->` closes in a target context file → `malformed-markers` |
|
|
43
|
+
| 6 | user-cancelled | step 1 §6 gate `[X]`/cancel; step 1 §1b snippet root: the layout question [S]/[X] or the mismatch gate (a)/(c); step 4 §8 gate `[X]`/cancel; step 4 §4c.1 orphan-row (c) Cancel; any prompt accepting `cancel`/`exit`/`:q` → `user-cancelled` |
|