bmad-module-skill-forge 2.1.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 +51 -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 +14 -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 +117 -9
- package/src/shared/scripts/skf-detect-docs.py +892 -4
- 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 +215 -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 +17 -6
- 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 +55 -18
- package/src/skf-create-skill/references/sub/ccc-discover.md +18 -7
- package/src/skf-create-skill/references/sub/fetch-docs.md +106 -57
- 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 -89
- package/src/skf-setup/references/detect-and-tier.md +58 -66
- 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 -645
- 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,28 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
nextStepFile: 'token-report.md'
|
|
3
|
-
|
|
4
|
-
#
|
|
5
|
-
# `
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
# atomic temp-file + rename, marker preservation, and post-write verify.
|
|
9
|
-
# HALT if no candidate exists — the in-prompt prose path silently regresses
|
|
10
|
-
# the Case 4 (malformed markers) HARD HALT guarantee.
|
|
11
|
-
rebuildManagedSectionsProbeOrder:
|
|
12
|
-
- '{project-root}/_bmad/skf/shared/scripts/skf-rebuild-managed-sections.py'
|
|
13
|
-
- '{project-root}/src/shared/scripts/skf-rebuild-managed-sections.py'
|
|
14
|
-
# Resolve `{manifestOpsHelper}` similarly. §9b uses `read` / `set` for
|
|
15
|
-
# atomic v2-schema-aware manifest mutation (handles v1→v2 migration and
|
|
16
|
-
# `platforms`→`ides` rename internally).
|
|
17
|
-
manifestOpsProbeOrder:
|
|
18
|
-
- '{project-root}/_bmad/skf/shared/scripts/skf-manifest-ops.py'
|
|
19
|
-
- '{project-root}/src/shared/scripts/skf-manifest-ops.py'
|
|
20
|
-
# Resolve `{atomicWriteHelper}` similarly. §6 Case 1 (Create) and §6
|
|
21
|
-
# Case 2 (Append) use it via `write` for safe artifact emission — the
|
|
22
|
-
# in-prompt write would risk half-written files on process kill.
|
|
23
|
-
atomicWriteProbeOrder:
|
|
24
|
-
- '{project-root}/_bmad/skf/shared/scripts/skf-atomic-write.py'
|
|
25
|
-
- '{project-root}/src/shared/scripts/skf-atomic-write.py'
|
|
3
|
+
# SKILL.md's On Activation resolved {rebuildManagedSectionsHelper}, which
|
|
4
|
+
# builds and writes every managed section (`assemble` builds each body,
|
|
5
|
+
# `check` picks the write and enforces the malformed-marker halt, `read`
|
|
6
|
+
# shows the old section, `insert` / `replace` write atomically and verify),
|
|
7
|
+
# and {manifestOpsHelper}, whose `set` records each skill in §9b.
|
|
26
8
|
---
|
|
27
9
|
|
|
28
10
|
<!-- Config: communicate in {communication_language}. Render the change preview and managed section in {document_output_language}. -->
|
|
@@ -31,15 +13,15 @@ atomicWriteProbeOrder:
|
|
|
31
13
|
|
|
32
14
|
## STEP GOAL:
|
|
33
15
|
|
|
34
|
-
To update the
|
|
16
|
+
To update the SKF managed section in each target context file (CLAUDE.md, AGENTS.md or .cursorrules) through `skf-rebuild-managed-sections.py`, which builds the section from every exported skill and writes it by the four cases of ADR-J (Create, Append, Regenerate, Malformed Markers halt), to record every skill of the batch in the export manifest, and then to write each skill's staged `context-snippet.md` into its package.
|
|
35
17
|
|
|
36
18
|
## Rules
|
|
37
19
|
|
|
38
|
-
-
|
|
39
|
-
- Do not
|
|
40
|
-
-
|
|
41
|
-
-
|
|
42
|
-
-
|
|
20
|
+
- The helper builds and writes the section: never type a snippet, a marker or a date into a context file, and never change the content outside the markers
|
|
21
|
+
- Do not write a context file without user confirmation (§8): this modifies shared project files, and a dry run writes none
|
|
22
|
+
- If `passive_context: false` was detected in step 1, skip to §9b: the export manifest still records the export
|
|
23
|
+
- **Multi-skill mode:** this step runs once for the whole batch: each body lists every skill in `skill_batch` (§4a), one gate confirms every target (§8), §9b records every skill, and §9c writes each skill's snippet. See step 1 §1c.
|
|
24
|
+
- Every HALT names its exit code, `halt_reason` and phase; in headless mode it first emits its envelope as `references/result-envelope.md` states
|
|
43
25
|
|
|
44
26
|
## MANDATORY SEQUENCE
|
|
45
27
|
|
|
@@ -47,194 +29,122 @@ To update the managed `<!-- SKF:BEGIN/END -->` section in the platform-appropria
|
|
|
47
29
|
|
|
48
30
|
**If `passive_context: false` was detected in step 1:**
|
|
49
31
|
|
|
50
|
-
"**Passive context disabled in preferences.yaml. Skipping context
|
|
32
|
+
"**Passive context disabled in preferences.yaml. Skipping the context files; the export manifest still records this export.**"
|
|
51
33
|
|
|
52
|
-
|
|
34
|
+
Run §9b, then auto-proceed to {nextStepFile}.
|
|
53
35
|
|
|
54
|
-
**If `passive_context: true` (default):** Continue to
|
|
36
|
+
**If `passive_context: true` (default):** Continue to §2.
|
|
55
37
|
|
|
56
|
-
### 2.
|
|
38
|
+
### 2. Stage Folder
|
|
57
39
|
|
|
58
|
-
|
|
40
|
+
Step 3 bound `{export_stage_dir}`, the run's folder outside the project that holds each skill's snippet draft under `drafts/`. This step stages each target's new section body under its `previews/` folder, so nothing lands beside a context file before the §8 gate, and deletes the folder on every exit: the §8 dry run and cancel, the end of §9c, the orphan-row (c) Cancel and every HALT in this step.
|
|
59
41
|
|
|
60
|
-
### 3. Determine Target
|
|
42
|
+
### 3. Determine Target Files
|
|
61
43
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
For each entry in `target_context_files`, resolve target file path: `{context_file}`
|
|
65
|
-
|
|
66
|
-
**If multiple context files:** Sections 4-9a execute as a loop — one full pass per target context file. Each iteration uses the same skill index but rewrites root paths per context file's `skill_root` (section 4d) and writes to the target context file. Section 9b executes once after all iterations complete.
|
|
67
|
-
|
|
68
|
-
**Processing order:** Process context files in the order listed in `target_context_files`.
|
|
44
|
+
Step 1 resolved `target_context_files` through `resolve-targets`: one `{context_file, skill_root, ides}` entry per file. Process the targets in that order. A context file's path is `{context_path}`, its `{context_file}` in `{project-root}`, its skill root `{target_skill_root}` is that entry's own `skill_root`, and `{target_paths}` is the `{context_path}` of every target, each quoted, space-separated, in that order.
|
|
69
45
|
|
|
70
46
|
#### 3b. Detect Orphaned Platform Files (Stale Managed Sections)
|
|
71
47
|
|
|
72
|
-
A context file becomes orphaned when its IDE is removed from `config.yaml` after a prior export
|
|
73
|
-
|
|
74
|
-
**Cheap pre-check (always run, ~3 file existence checks):** build `orphaned_context_files` — for each known context file in `{CLAUDE.md, .cursorrules, AGENTS.md}` that is NOT in `target_context_files`, check whether it exists on disk and contains the `<!-- SKF:BEGIN -->` marker. If yes, add `{context_file, file_path}` to `orphaned_context_files`.
|
|
75
|
-
|
|
76
|
-
**If `orphaned_context_files` is non-empty:** load `references/orphan-context-detection.md` and follow its (a) clear / (b) keep / (c) rewrite gate protocol. The reference handles user prompting, headless default (keep), and downstream-state recording (`orphans_cleared`, `orphans_rewritten`, `rewrite_context_files`). When the user chooses (c), the §4–§9a loop iterates over `target_context_files + rewrite_context_files`.
|
|
77
|
-
|
|
78
|
-
**If `orphaned_context_files` is empty:** proceed to §4.
|
|
79
|
-
|
|
80
|
-
### 4. Rebuild Complete Skill Index
|
|
81
|
-
|
|
82
|
-
#### 4a. Read Export Manifest (v2 — version-aware)
|
|
48
|
+
A context file becomes orphaned when its IDE is removed from `config.yaml` after a prior export: it still holds an SKF managed section that lists stale skill versions, but no later export rewrites it.
|
|
83
49
|
|
|
84
|
-
|
|
50
|
+
Run `check` on each file of step 1's `{other_context_files}`, the known context files no configured IDE maps to:
|
|
85
51
|
|
|
86
52
|
```bash
|
|
87
|
-
python3 {
|
|
53
|
+
python3 {rebuildManagedSectionsHelper} "{context_path}" check
|
|
88
54
|
```
|
|
89
55
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
**Schema reference:** `references/manifest-rebuild.md` documents the v2 shape, the status enum (`active`/`archived`/`deprecated`/`draft`), the v1 migration path, and the `active_version` integrity invariant. Load that file only when an inline schema reminder is needed — the helper enforces the shape so the in-prompt prose is not load-bearing.
|
|
93
|
-
|
|
94
|
-
**Integrity guard:** if the helper returns an entry where `active_version` does not resolve to a key in `versions`, the manifest is inconsistent. Skip the affected skill and log: "**Manifest integrity warning:** `{skill-name}.active_version = v{active_version}` has no matching entry under `versions`. Skipping. Re-run `[EX] Export Skill` on `{skill-name}` to repair the manifest entry."
|
|
95
|
-
|
|
96
|
-
**If the manifest does not exist** (first export or fresh forge): the envelope wraps an empty manifest — `result["manifest"]` is `{"schema_version": "2", "exports": {}}`, so `result["manifest"]["exports"]` is `{}`. Only the current export target will appear in the rebuilt index.
|
|
56
|
+
A file whose `case` is `regenerate` holds a managed section: add `{context_file, file_path}` to `orphaned_context_files`, with its `{context_path}` as `file_path`. A `malformed` one is left as it is, with the warning "`{context_file}` has malformed SKF markers, so it was left as it is: {error}". Any other case is not orphaned.
|
|
97
57
|
|
|
98
|
-
|
|
58
|
+
**If `orphaned_context_files` is non-empty:** load `references/orphan-context-detection.md` and follow its (a) clear / (b) keep / (c) rewrite gate protocol. It handles user prompting, the headless default (keep), and the state it records (`orphans_cleared`, `orphans_rewritten`, `rewrite_context_files`). Each file the user chose to rewrite joins the targets for §4 to §9, with `.agents/skills/` as its skill root and no IDEs, and `{target_paths}` lists it too.
|
|
99
59
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
1. Start with the manifest `exports` entries that survived the §4a integrity guard — those whose `active_version` resolves to a key in `versions` (if manifest exists)
|
|
103
|
-
2. For each surviving skill, record its `active_version` from the manifest (v2 schema)
|
|
104
|
-
3. The §4a integrity guard already skipped (and warned about) any entry whose `active_version` has no matching `versions` key, so build only from those survivors — no re-check or re-warning here.
|
|
105
|
-
4. **Exclude deprecated skills:** If the `active_version` entry in `versions.{active_version}` has `status: "deprecated"`, skip this skill entirely — it has been dropped via drop-skill workflow and must not appear in the managed section. Log: "Skipping {skill-name} — active version v{active_version} is deprecated"
|
|
106
|
-
5. Add the current export target skill name (ensures it is always included even before manifest is written) — use the version from `{resolved_skill_package}/metadata.json` as its `active_version`
|
|
107
|
-
6. This is the **exported skill set** — each entry has a skill name and its resolved `active_version`
|
|
108
|
-
|
|
109
|
-
#### 4c. Resolve and Filter Snippets (manifest-driven — replaces glob scan)
|
|
110
|
-
|
|
111
|
-
Instead of globbing `{skills_output_folder}/*/context-snippet.md`, resolve snippets from the exported skill set built in 4b:
|
|
112
|
-
|
|
113
|
-
**For each skill in the exported skill set:**
|
|
114
|
-
1. Resolve `{skill_package}` using the skill's `active_version`: `{skills_output_folder}/{skill-name}/{active_version}/{skill-name}/`
|
|
115
|
-
2. Read `{skill_package}/context-snippet.md`
|
|
116
|
-
3. **If snippet exists:** Add to skill index
|
|
117
|
-
4. **If snippet does not exist at the versioned path:** Check for `active` symlink at `{skills_output_folder}/{skill-name}/active/{skill-name}/context-snippet.md`.
|
|
118
|
-
5. **If still not found, try the flat layout:** Read `{skills_output_folder}/{skill-name}/context-snippet.md` — a skill still on the pre-versioned flat layout (see `knowledge/version-paths.md` "Migration: Flat to Versioned"). This mirrors the flat-path fallback used when resolving a skill's SKILL.md in `load-skill.md` §1, so a manifest entry (or a first-export `--all` entry) that is still flat on disk is not silently dropped from the managed section.
|
|
119
|
-
6. **If none of the three paths yields a snippet, skip with warning:** "Snippet missing for {skill-name} v{active_version} — skipping from managed section"
|
|
120
|
-
|
|
121
|
-
**Skills NOT in the exported skill set are never scanned** — they have not been through export-skill and must not appear in the managed section (ADR-K).
|
|
122
|
-
|
|
123
|
-
**If no snippets pass the filter:** Generate managed section with zero skills — header only, no skill entries.
|
|
124
|
-
|
|
125
|
-
#### 4c.1 Detect Orphaned Managed-Section Rows (manifest-absent skills)
|
|
126
|
-
|
|
127
|
-
A managed-section row becomes orphaned when a `[skill-name v...]` entry already exists in the prior managed section but the skill is not in the exported skill set built in 4b — typically an externally-installed skill authored in a different repo and dropped into `{skills_output_folder}` without going through export-skill. Strict ADR-K would silently drop such rows, but the user's managed section is load-bearing — silent removal is a regression.
|
|
128
|
-
|
|
129
|
-
**Cheap pre-check (always run before §5 assembly).** Scan **every** target context file (not just the first), deduplicate by `(skill_name, version)`, and present one consolidated gate. Asymmetric orphans — a row present in `.cursorrules` but absent from `CLAUDE.md`, or vice versa — must be detected; otherwise the §4 rebuild loop silently overwrites the orphan-bearing file's content (ADR-J violation: silent loss of user content).
|
|
130
|
-
|
|
131
|
-
The parse / dedup-by-`(skill_name, version)` / set-diff-against-the-exported-set is deterministic marker surgery with one correct answer per input — a mis-parsed row silently drops an installed skill from the rebuilt managed section (the ADR-J/K regression this gate guards against). Delegate it to `{rebuildManagedSectionsHelper}` (resolve from `{rebuildManagedSectionsProbeOrder}` in frontmatter — first existing path wins; if no candidate exists, the same HALT as §9 applies: exit code 4, `halt_reason: "context-rebuild-failed"`). Do not re-derive the rows in-prompt.
|
|
60
|
+
**If `orphaned_context_files` is empty:** proceed to §4.
|
|
132
61
|
|
|
133
|
-
|
|
62
|
+
### 4. Build the Managed Section
|
|
134
63
|
|
|
135
|
-
|
|
136
|
-
python3 {rebuildManagedSectionsHelper} orphan-detect {context-file-1} {context-file-2} … --exported-skills {name1,name2,…}
|
|
137
|
-
```
|
|
64
|
+
#### 4a. The Skills It Lists
|
|
138
65
|
|
|
139
|
-
|
|
66
|
+
`assemble` lists each skill of the export manifest whose active version is not deprecated and, through `--include`, every skill in `skill_batch` at the version in its `{resolved_skill_package}/metadata.json`, so a first export, a batch member the manifest does not list yet, and a skill the step 1 manifest-lag guard resolved to a newer version all appear at the version this export publishes. Bind `{batch_includes}` to the comma-joined `{skill-name}@{version}` of every skill in `skill_batch`. `--snippet-dir` hands it the drafts step 3 staged, so a batch skill's row is its new snippet.
|
|
140
67
|
|
|
141
|
-
|
|
142
|
-
{"status": "ok", "orphan_managed_rows": [{"skill_name": "…", "version": "…", "snippet_text": "…", "source_files": ["…"]}]}
|
|
143
|
-
```
|
|
68
|
+
#### 4b. Assemble One Body per Target
|
|
144
69
|
|
|
145
|
-
|
|
70
|
+
For each target, run:
|
|
146
71
|
|
|
147
|
-
|
|
72
|
+
```bash
|
|
73
|
+
python3 {rebuildManagedSectionsHelper} assemble "{context_path}" \
|
|
74
|
+
--skills-folder "{skills_output_folder}" --skill-root "{target_skill_root}" \
|
|
75
|
+
--include {batch_includes} --snippet-dir "{export_stage_dir}/drafts" \
|
|
76
|
+
--orphan-sources {target_paths} --orphans {orphan_mode} \
|
|
77
|
+
--out "{export_stage_dir}/previews/{context_file}.skf-content" \
|
|
78
|
+
[--skill-root-override "{snippet_skill_root_override}"]
|
|
79
|
+
```
|
|
148
80
|
|
|
149
|
-
|
|
81
|
+
Add `--skill-root-override` only when `{snippet_skill_root_override}` is set (by `config.yaml`, or for this run by step 1's snippet-root option (d)). `{orphan_mode}` is `keep` unless §4c.1 drops the orphan rows. The helper writes the body to the `--out` file, with no marker and no trailing newline, and prints its result as JSON. From each target's result bind `{content_file}` ← `content_file`, `{n_single}` ← `n_single` and `{n_stack}` ← `n_stack`. A non-zero exit writes nothing: HALT (exit code 4, `halt_reason: "context-rebuild-failed"`, phase `update-context §4b`) and report `{context_file}: {error}` (for example a context file that is not UTF-8 text: the error says how to fix it).
|
|
150
82
|
|
|
151
|
-
|
|
83
|
+
When the first result's `malformed_context_files` is not empty, run the §5 `check` on those files now and take its `malformed` HALT, before §4c.1 asks anything: a target whose `<!-- SKF:BEGIN` marker no `<!-- SKF:END -->` closes is never written.
|
|
152
84
|
|
|
153
|
-
|
|
85
|
+
#### 4c. Report What Was Left Out
|
|
154
86
|
|
|
155
|
-
|
|
87
|
+
Every call reads the same manifest and snippets, so report these once, from the first result:
|
|
156
88
|
|
|
157
|
-
|
|
89
|
+
- each `skipped_integrity[]` entry: "**Manifest integrity warning:** `{skill_name}`: {reason}. Skipping. Re-run `[EX] Export Skill` on `{skill_name}` to repair the manifest entry."
|
|
90
|
+
- each `skipped_deprecated[]` entry: "Skipping {skill_name}: active version v{version} is deprecated"
|
|
91
|
+
- each `skipped_missing_snippet[]` entry: "Snippet missing for {skill_name} v{version}: skipping from managed section"
|
|
92
|
+
- each `skipped_malformed_snippet[]` entry: "Snippet of {skill_name} v{version} skipped: {reason}"
|
|
93
|
+
- each `warnings[]` line as it is
|
|
158
94
|
|
|
159
|
-
|
|
160
|
-
2. Extract the current prefix by stripping the trailing `{skill-name}/` from the root value
|
|
161
|
-
3. **Resolve the effective target prefix:** If `snippet_skill_root_override` is set in config.yaml, use the override value as the effective target prefix for this rebuild — by the override contract every skill in the repo lives under that single shared on-disk directory, so the managed section must reference the override for *every* snippet (not just the ones that already match it). Otherwise, use the current target's `skill_root` as the effective target prefix.
|
|
162
|
-
4. Compare the extracted prefix against the effective target prefix
|
|
163
|
-
5. If they differ, replace the prefix with the effective target prefix, preserving the skill name. When the override is set, this rewrites stale per-IDE prefixes carried by sibling snippets that were exported before the override was adopted, so the rebuilt managed section uniformly references the real on-disk location instead of mixing override and per-IDE paths.
|
|
164
|
-
6. Example: if snippet has `root: .claude/skills/my-lib/` but target skill_root is `.windsurf/skills/`, rewrite to `root: .windsurf/skills/my-lib/`
|
|
165
|
-
7. Example: if `snippet_skill_root_override: skills/` is set, the effective target prefix is `skills/` regardless of the IDE mapping. A snippet with `root: skills/my-lib/` passes through unchanged; a sibling snippet with `root: .claude/skills/my-other/` (carried over from a pre-override export) is rewritten to `root: skills/my-other/`.
|
|
95
|
+
With no skill to list, each body holds the header alone (`0 skills|0 stack`).
|
|
166
96
|
|
|
167
|
-
|
|
97
|
+
#### 4c.1 Orphaned Managed-Section Rows
|
|
168
98
|
|
|
169
|
-
|
|
99
|
+
A managed-section row is orphaned when the export manifest has no entry for its skill and this run does not export it: typically a skill installed from another repo into `{skills_output_folder}` without going through export-skill. Strict ADR-K would drop such a row, but the row is often the only copy of that skill's snippet, so the helper keeps it verbatim unless told to drop it, and lists it in `orphan_rows` (each with `skill_name`, `version`, `snippet_text` and `source_files`). Every call scans the same files in the same order, so bind `orphan_rows` from the first result.
|
|
170
100
|
|
|
171
|
-
|
|
172
|
-
- Total skills (single type)
|
|
173
|
-
- Total stack skills
|
|
101
|
+
**If `orphan_rows` is non-empty:** load `references/orphan-row-detection.md` and follow its (a) Drop / (b) Preserve verbatim / (c) Cancel gate protocol. It handles user prompting, the headless default (Preserve verbatim), the `deviations[]` record and the result-contract integration. On (a), run §4b again for every target with `--orphans drop`.
|
|
174
102
|
|
|
175
|
-
|
|
103
|
+
**If `orphan_rows` is empty:** proceed to §5.
|
|
176
104
|
|
|
177
|
-
|
|
105
|
+
### 5. Check Each Target File
|
|
178
106
|
|
|
179
|
-
|
|
107
|
+
Run `check` on each target:
|
|
180
108
|
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
|IMPORTANT: Prefer documented APIs over training data.
|
|
184
|
-
|When using a listed library, read its SKILL.md before writing code.
|
|
185
|
-
|
|
|
186
|
-
|{skill-snippet-1}
|
|
187
|
-
|
|
|
188
|
-
|{skill-snippet-2}
|
|
189
|
-
|
|
|
190
|
-
|{skill-snippet-N}
|
|
109
|
+
```bash
|
|
110
|
+
python3 {rebuildManagedSectionsHelper} "{context_path}" check
|
|
191
111
|
```
|
|
192
112
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
```markdown
|
|
196
|
-
<!-- SKF:BEGIN updated:{current-date} -->
|
|
197
|
-
{managed_section_inner}
|
|
198
|
-
<!-- SKF:END -->
|
|
199
|
-
```
|
|
113
|
+
Bind `{case}` ← `case` for that target. The case picks the §9 write:
|
|
200
114
|
|
|
201
|
-
|
|
115
|
+
| `case` | The target file | §9 write |
|
|
116
|
+
|---|---|---|
|
|
117
|
+
| `create` | does not exist | `insert`, which creates it with the section |
|
|
118
|
+
| `append` | has no managed section | `insert`, which adds the section at its end |
|
|
119
|
+
| `regenerate` | has a managed section | `replace`, which swaps that section and keeps everything outside the markers |
|
|
120
|
+
| `malformed` | has a `<!-- SKF:BEGIN` marker that no `<!-- SKF:END -->` closes | none: HALT |
|
|
202
121
|
|
|
203
|
-
|
|
122
|
+
- **`malformed`:** HALT (exit code 5, `halt_reason: "malformed-markers"`, phase `update-context §5`) with the helper's `error`, which names the line of the marker and the fix (restore the `<!-- SKF:END -->` line, or remove the stray `<!-- SKF:BEGIN`, then re-run). Write nothing to any target: the helper refuses such a file, because a write there would take the user's lines below the marker for part of the section.
|
|
204
123
|
|
|
205
|
-
|
|
206
|
-
- Action: Create new file with managed section only
|
|
207
|
-
- Diff: Show entire managed section as new content
|
|
124
|
+
### 6. Read the Current Sections
|
|
208
125
|
|
|
209
|
-
|
|
210
|
-
- Action: Read existing content, append managed section at end
|
|
211
|
-
- Diff: Show managed section being appended after existing content
|
|
212
|
-
- Preserved: ALL existing content untouched
|
|
126
|
+
For each `regenerate` target, read the section §9 replaces:
|
|
213
127
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
- Preserved: ALL content before `<!-- SKF:BEGIN` and after `<!-- SKF:END -->`
|
|
128
|
+
```bash
|
|
129
|
+
python3 {rebuildManagedSectionsHelper} "{context_path}" read
|
|
130
|
+
```
|
|
218
131
|
|
|
219
|
-
|
|
220
|
-
- Action: HALT (exit code 5, `halt_reason: "malformed-markers"`) with warning: "Malformed SKF markers detected in `{target-file}` — `<!-- SKF:BEGIN` found but `<!-- SKF:END -->` is missing. Please restore the end marker manually before running export."
|
|
221
|
-
- Do NOT attempt to write or append — the file is in an inconsistent state.
|
|
222
|
-
- In headless mode, emit the error envelope per `references/result-envelope.md` with `manifest_path: null`, `context_files_updated: []`.
|
|
132
|
+
Bind `{old_section}` ← `content` for that target; §7 shows it beside the new body.
|
|
223
133
|
|
|
224
134
|
### 7. Present Change Preview
|
|
225
135
|
|
|
226
136
|
"**Context update prepared.{if multi-platform: ' (platform {i}/{total}: {platform})'}**
|
|
227
137
|
|
|
228
|
-
**Target:** `{
|
|
229
|
-
**Case:** {
|
|
230
|
-
**Skills in index:** {
|
|
138
|
+
**Target:** `{context_file}`
|
|
139
|
+
**Case:** {Create / Append / Regenerate}
|
|
140
|
+
**Skills in index:** {n_single} skills, {n_stack} stack
|
|
231
141
|
|
|
232
142
|
**Changes:**
|
|
233
143
|
|
|
234
|
-
{Show diff preview
|
|
235
|
-
- For
|
|
236
|
-
- For
|
|
237
|
-
- For
|
|
144
|
+
{Show the diff preview from the new body in `{content_file}`:}
|
|
145
|
+
- For Create: the new file, which holds only the section
|
|
146
|
+
- For Append: `...existing content preserved...` followed by the section
|
|
147
|
+
- For Regenerate: `{old_section}` beside the new body, with the content outside the markers preserved
|
|
238
148
|
|
|
239
149
|
**Content outside markers:** {preserved / n/a (new file)}
|
|
240
150
|
|
|
@@ -246,118 +156,89 @@ Assemble the managed section in **two shapes** — the §9 write paths consume d
|
|
|
246
156
|
|
|
247
157
|
"**[DRY RUN] No files will be written. Preview above shows what would change.**
|
|
248
158
|
|
|
159
|
+
**[DRY RUN] Export manifest would be updated for {skill-name-list}: ides: {ides_written}.**
|
|
160
|
+
|
|
249
161
|
**Proceeding to token report...**"
|
|
250
162
|
|
|
251
|
-
|
|
163
|
+
List every skill in `skill_batch`, and give `{ides_written}` as §9b defines it, over the targets above, or `none` when it is empty. §9 to §9c do not run: delete the `{export_stage_dir}` folder, then auto-proceed to {nextStepFile}.
|
|
252
164
|
|
|
253
165
|
**If NOT dry-run:**
|
|
254
166
|
|
|
255
|
-
Display: "**Select:** [C] Continue
|
|
167
|
+
Display: "**Select:** [C] Continue: write changes to {context_file} | [X] Cancel and exit (or type `cancel` / `exit` / `:q`)"
|
|
256
168
|
|
|
257
169
|
**Multi-target behavior:** When processing multiple context files, present all previews together before asking for a single confirmation. After confirmation, write all target files sequentially, verifying each one.
|
|
258
170
|
|
|
259
|
-
"**Targets:** {list
|
|
171
|
+
"**Targets:** {list each context_file with its case}
|
|
260
172
|
**Ready to write changes to all targets?**"
|
|
261
173
|
|
|
262
174
|
Display: "**Select:** [C] Continue — write changes to all targets | [X] Cancel and exit"
|
|
263
175
|
|
|
264
176
|
#### Gate handling
|
|
265
177
|
|
|
266
|
-
- **[C]
|
|
267
|
-
- **[X]** / `cancel` / `exit` / `:q`
|
|
178
|
+
- **[C]**: write the targets (§9), record the export (§9b) and write the snippets (§9c), then load, read entirely, and execute `{nextStepFile}`.
|
|
179
|
+
- **[X]** / `cancel` / `exit` / `:q`: delete the `{export_stage_dir}` folder, display "Cancelled: no context files were written." and HALT (exit code 6, `halt_reason: "user-cancelled"`, phase `update-context §8`).
|
|
268
180
|
- **Any other input** — help the user respond, then redisplay this gate.
|
|
269
|
-
- **Headless** [default C]: auto-approve with [C], log "headless: auto-approve context file update".
|
|
270
181
|
- **Dry-run**: auto-proceed without writing.
|
|
182
|
+
- **GATE [default: C]**: headless, record the decision in the run sink with the command below, log "headless: auto-approve context file update", then auto-approve with [C]. If `record` exits non-zero, display its error line and go on: a failed `record` never stops the run.
|
|
271
183
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
- `{atomicWriteHelper}` ← first existing path in `{atomicWriteProbeOrder}` (used for Case 1)
|
|
278
|
-
- `{manifestOpsHelper}` ← first existing path in `{manifestOpsProbeOrder}` (used in §9b)
|
|
279
|
-
|
|
280
|
-
If any helper has no existing candidate, HALT (exit code 4, `halt_reason: "context-rebuild-failed"`) and emit the error envelope per `references/result-envelope.md` — the rewrite's safety guarantees depend on these helpers and a fall-through to LLM-driven writes would silently regress atomicity, marker preservation, and the Case 4 malformed-marker HARD HALT contract.
|
|
281
|
-
|
|
282
|
-
**Stage content via a shell-safe channel (all cases).** Managed-section snippets routinely contain backticks and `$` — API names like `` `Room::connect(...)` ``, tokens like `$threshold` and `${…}`. Inlining them as a double-quoted shell argument (`--content "…"`) or via `echo "…"` lets bash run command substitution and variable expansion, silently corrupting the written bytes — and because the helper's byte-identity verify runs against the already-corrupted string, it would still report success. No quoting style is safe (content can also contain single quotes, e.g. `'eager' | 'on-demand'`), so **never** inline the section into the command. Instead write the assembled section to a staging file with your file-write tool (which performs no shell interpretation), then feed it to the helper via stdin redirection — the helper reads stdin whenever `--content` is absent:
|
|
184
|
+
```bash
|
|
185
|
+
uv run {emitEnvelopeHelper} record --workflow skf-export-skill --run-dir "{run_dir}" --decision <<'SKF_JSON'
|
|
186
|
+
{"gate":"update-context.write-confirmation","default_action":"C","taken_action":"C","reason":"headless: auto-approve context file update"}
|
|
187
|
+
SKF_JSON
|
|
188
|
+
```
|
|
283
189
|
|
|
284
|
-
|
|
285
|
-
- For **Case 1**, write `{managed_section_full}` to `{target-file}.skf-content` followed by a single trailing newline (matches the verbatim file-end newline convention).
|
|
286
|
-
- After the helper reports success, delete `{target-file}.skf-content`.
|
|
190
|
+
### 9. Write and Verify (Non-Dry-Run Only)
|
|
287
191
|
|
|
288
|
-
For each target
|
|
192
|
+
For each target, in order, feed the body §4b staged at `{content_file}` to the write its §5 case picked, by stdin redirection. Never pass a body inline as `--content "…"` or through `echo`: snippets carry backticks, `$` and quotes, which the shell expands, and the helper checks the text it received, so it would report success on corrupted bytes.
|
|
289
193
|
|
|
290
|
-
**
|
|
194
|
+
**Create and Append:**
|
|
291
195
|
|
|
292
196
|
```bash
|
|
293
|
-
python3 {
|
|
197
|
+
python3 {rebuildManagedSectionsHelper} "{context_path}" insert < "{content_file}"
|
|
294
198
|
```
|
|
295
199
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
**Case 2 (Append — file exists, no `<!-- SKF:BEGIN` marker):**
|
|
200
|
+
**Regenerate:**
|
|
299
201
|
|
|
300
202
|
```bash
|
|
301
|
-
python3 {rebuildManagedSectionsHelper} {
|
|
203
|
+
python3 {rebuildManagedSectionsHelper} "{context_path}" replace < "{content_file}"
|
|
302
204
|
```
|
|
303
205
|
|
|
304
|
-
|
|
206
|
+
Both write the `<!-- SKF:BEGIN updated:{date} -->` and `<!-- SKF:END -->` markers around the body themselves (the date from the clock), write the file atomically (temp file + rename) and read it back to check the markers and the bytes outside them. They refuse (exit 1) a body that holds a marker of its own, and a file whose markers became malformed after §5, and leave that file unchanged. They print their result as JSON on stdout and exit 0 only when `status` is `"ok"`.
|
|
305
207
|
|
|
306
|
-
|
|
208
|
+
On a non-zero exit, bind `{context_error}` ← `error` (the helper's stderr when stdout holds no JSON, such as a Python traceback), HALT (exit code 4, `halt_reason: "context-rebuild-failed"`, phase `update-context §9`) and report `{context_file}: {context_error}`. The targets already written stay written.
|
|
307
209
|
|
|
308
|
-
|
|
309
|
-
python3 {rebuildManagedSectionsHelper} {target-file} replace < "{target-file}.skf-content"
|
|
310
|
-
```
|
|
210
|
+
On success per file, report "**{context_file} updated successfully.** Verified by `{rebuildManagedSectionsHelper}`." and add it to `context_files_updated`.
|
|
311
211
|
|
|
312
|
-
|
|
212
|
+
### 9b. Update Export Manifest
|
|
313
213
|
|
|
314
|
-
**
|
|
214
|
+
**This section runs once, after every target is written** (§1 sends a run with passive context off straight here; a dry run runs no `set`, as the dry-run paragraph below says). It records each skill in `skill_batch` at the version in its `{resolved_skill_package}/metadata.json`.
|
|
315
215
|
|
|
316
|
-
|
|
216
|
+
**`ides_written`** is the list of IDE identifiers from `config.yaml` `ides` (e.g. `claude-code`, `cursor`, `github-copilot`) whose context file §9 wrote: the `ides` of each `target_context_files` entry §9 wrote, joined, deduplicated and sorted. It is never a context file name (`CLAUDE.md`) or a skill root (`.claude/skills/`). A file §3b rewrote adds no IDE, and with passive context off `ides_written` is empty.
|
|
317
217
|
|
|
318
|
-
|
|
319
|
-
- In headless mode, emit the error envelope per `references/result-envelope.md`.
|
|
320
|
-
- Continue to the next target file only on success — partial-batch writes are acceptable in single-skill mode but the overall envelope reports per-target outcomes.
|
|
218
|
+
For each skill, run `set`, with `--ides` only when `ides_written` is not empty:
|
|
321
219
|
|
|
322
|
-
|
|
220
|
+
```bash
|
|
221
|
+
python3 {manifestOpsHelper} {skills_output_folder} set {skill-name} {version} [--ides {ides_written}]
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
`{ides_written}` is comma-joined. `set` does the whole update, migrating a v1 manifest first, and writes the manifest atomically (the v2 shape is in `references/manifest-rebuild.md`). It exits 0 with `status: "ok"` only once the manifest is written, so that result confirms the write. Once every `set` has exited 0, bind `{manifest_path}` ← `{skills_output_folder}/.export-manifest.json`, which step 6 reports; it stays null on a dry run and after a failed write.
|
|
323
225
|
|
|
324
|
-
|
|
226
|
+
**Dry-run mode:** Do NOT update the manifest. Display: "**[DRY RUN] Export manifest would be updated for {skill-name-list}: ides: {ides_written}.**" (list every skill in `skill_batch`; `ides_written` is empty with passive context off, so show `none`). A dry run with passive context on displayed this line at §8 and never reaches this section. Then auto-proceed to {nextStepFile}.
|
|
325
227
|
|
|
326
|
-
**
|
|
228
|
+
**Error handling:** If `set` exits non-zero, HALT (exit code 4, `halt_reason: "manifest-write-failed"`, phase `update-context §9b`) with the helper's `error` (its stderr when stdout holds no JSON). The context files §9 wrote stay written, and no snippet is written: re-run `[EX] Export Skill` on the batch, which writes the same sections again, records the manifest and writes the snippets.
|
|
327
229
|
|
|
328
|
-
|
|
230
|
+
### 9c. Write the Snippets
|
|
329
231
|
|
|
330
|
-
|
|
331
|
-
2. Ensure `schema_version` is `"2"` (if v1 was migrated in section 4a, the migrated structure is already in context). If any version entry still has a legacy `platforms` key, rename it to `ides` in place (see §4a).
|
|
332
|
-
3. Compute `ides_written` — the set of IDE identifiers from `config.yaml.ides` whose mapped context file was successfully written in section 9 (deduplicated, sorted). When `--context-file` was passed explicitly, `ides_written` contains only the IDEs that map to that single context file.
|
|
333
|
-
4. For each skill in `skill_batch` (multi-skill mode) — or the single current skill (single-skill mode) — add or update its entry in v2 format:
|
|
334
|
-
```json
|
|
335
|
-
"{skill-name}": {
|
|
336
|
-
"active_version": "{version}",
|
|
337
|
-
"versions": {
|
|
338
|
-
"{version}": {
|
|
339
|
-
"ides": ["{ides_written}"],
|
|
340
|
-
"last_exported": "{current-date}",
|
|
341
|
-
"status": "active"
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
```
|
|
346
|
-
- `{version}` is the version from each skill's `{resolved_skill_package}/metadata.json`
|
|
347
|
-
- If the skill already has a manifest entry:
|
|
348
|
-
- Set `active_version` to the current version
|
|
349
|
-
- If the version already exists in `versions`, union its existing `ides` with `ides_written` (deduplicate, keep sorted), refresh `last_exported`, and set `status: "active"`
|
|
350
|
-
- If this is a new version, add it to `versions` with `status: "active"` and set any previously-active version's status to `"archived"`
|
|
351
|
-
- Preserve all other version entries in `versions` (do not delete archived versions)
|
|
352
|
-
5. Write the updated manifest atomically via `{manifestOpsHelper}` after all skills in the batch have been applied. For each skill / version pair, invoke:
|
|
232
|
+
**This section runs last, after §9b, and only when step 3 staged the snippets**: a run with passive context off has none, and a dry run never reaches it.
|
|
353
233
|
|
|
354
|
-
|
|
355
|
-
python3 {manifestOpsHelper} {skills_output_folder} set {skill-name} {version} --ides {ides_written}
|
|
356
|
-
```
|
|
234
|
+
For each skill in `skill_batch`, copy its measured draft into its package, byte for byte, so the count step 3 measured is the count of the written file:
|
|
357
235
|
|
|
358
|
-
|
|
236
|
+
```bash
|
|
237
|
+
cp "{export_stage_dir}/drafts/{skill-name}/context-snippet.md" "{resolved_skill_package}/context-snippet.md"
|
|
238
|
+
```
|
|
359
239
|
|
|
360
|
-
**
|
|
240
|
+
Report "**{skill-name}: context-snippet.md written** to `{resolved_skill_package}/context-snippet.md`." and add the file to `snippets_written`, which step 6 lists in the result contract.
|
|
361
241
|
|
|
362
|
-
|
|
242
|
+
On a failed copy, HALT (exit code 4, `halt_reason: "write-failed"`, phase `update-context §9c`) and report `{skill-name}: context-snippet.md was not written: {error}`. The context files, the export manifest and the snippets copied before it stay written: re-run `[EX] Export Skill` on the skills whose snippet was not written (this one and the ones after it).
|
|
363
243
|
|
|
244
|
+
Once every snippet is written, delete the `{export_stage_dir}` folder.
|