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,20 +1,67 @@
|
|
|
1
1
|
---
|
|
2
2
|
nextStepFile: 'report.md'
|
|
3
3
|
forgeTierConfig: '{sidecar_path}/forge-tier.yaml'
|
|
4
|
+
cccIndexCheckData: 'references/ccc-index-check.md'
|
|
5
|
+
# Resolve `{skillInventoryHelper}` by probing `{skillInventoryProbeOrder}` in
|
|
6
|
+
# order (installed SKF module path first, src/ dev-checkout fallback); first
|
|
7
|
+
# existing path wins. §1 runs its write check before any directory is
|
|
8
|
+
# created; without it, §1 writes only into a skill folder that does not exist yet.
|
|
9
|
+
skillInventoryProbeOrder:
|
|
10
|
+
- '{project-root}/_bmad/skf/shared/scripts/skf-skill-inventory.py'
|
|
11
|
+
- '{project-root}/src/shared/scripts/skf-skill-inventory.py'
|
|
4
12
|
# Resolve `{atomicWriteHelper}` by probing `{atomicWriteProbeOrder}` in order
|
|
5
13
|
# (installed SKF module path first, src/ dev-checkout fallback); first existing
|
|
6
|
-
# path wins. HALT if neither resolves
|
|
7
|
-
#
|
|
14
|
+
# path wins. HALT (exit code 3, helper-missing) if neither resolves: the
|
|
15
|
+
# active-symlink flip (§4) goes through the atomic helper, so §2 resolves it
|
|
16
|
+
# before anything is written.
|
|
8
17
|
atomicWriteProbeOrder:
|
|
9
18
|
- '{project-root}/_bmad/skf/shared/scripts/skf-atomic-write.py'
|
|
10
19
|
- '{project-root}/src/shared/scripts/skf-atomic-write.py'
|
|
20
|
+
# Resolve `{cccGitHygieneHelper}` to the first existing path. It keeps ccc's
|
|
21
|
+
# index folders and SKF's workspace lock out of git, and undoes the
|
|
22
|
+
# `.gitignore` edit `ccc init` makes in a workspace clone. If neither path
|
|
23
|
+
# exists, skip the call and continue: it never gates the workflow.
|
|
24
|
+
cccGitHygieneProbeOrder:
|
|
25
|
+
- '{project-root}/_bmad/skf/shared/scripts/skf-ccc-git-hygiene.py'
|
|
26
|
+
- '{project-root}/src/shared/scripts/skf-ccc-git-hygiene.py'
|
|
11
27
|
# Resolve `{forgeTierRwHelper}` by probing `{forgeTierRwProbeOrder}` in order
|
|
12
28
|
# (installed SKF module path first, src/ dev-checkout fallback); first existing
|
|
13
|
-
# path wins.
|
|
14
|
-
# comment-preserving
|
|
29
|
+
# path wins. §6 and §6b change the registry only through it, a
|
|
30
|
+
# comment-preserving round-trip with no prose fallback. If neither resolves,
|
|
31
|
+
# they skip the registry change with a warning: registration never halts the
|
|
32
|
+
# workflow.
|
|
15
33
|
forgeTierRwProbeOrder:
|
|
16
34
|
- '{project-root}/_bmad/skf/shared/scripts/skf-forge-tier-rw.py'
|
|
17
35
|
- '{project-root}/src/shared/scripts/skf-forge-tier-rw.py'
|
|
36
|
+
# Resolve `{mergeCccExclusionsHelper}` to the first existing path. §6b
|
|
37
|
+
# prepares the settings.yml of SKF's workspace clone with it; if neither path
|
|
38
|
+
# exists, §6b skips the index of a remote source.
|
|
39
|
+
mergeCccExclusionsProbeOrder:
|
|
40
|
+
- '{project-root}/_bmad/skf/shared/scripts/skf-merge-ccc-exclusions.py'
|
|
41
|
+
- '{project-root}/src/shared/scripts/skf-merge-ccc-exclusions.py'
|
|
42
|
+
# Resolve `{extractionInventoryHelper}` to the first existing path; HALT
|
|
43
|
+
# (exit code 3, helper-missing) if neither exists. §2 writes
|
|
44
|
+
# extraction-rules.yaml from the extraction inventory through its `rules`.
|
|
45
|
+
extractionInventoryProbeOrder:
|
|
46
|
+
- '{project-root}/_bmad/skf/shared/scripts/skf-extraction-inventory.py'
|
|
47
|
+
- '{project-root}/src/shared/scripts/skf-extraction-inventory.py'
|
|
48
|
+
# Resolve `{promoteStagedHelper}` to the first existing path; HALT (exit
|
|
49
|
+
# code 3, helper-missing) if neither exists. §3 promotes the staged skill
|
|
50
|
+
# through it.
|
|
51
|
+
promoteStagedProbeOrder:
|
|
52
|
+
- '{project-root}/_bmad/skf/shared/scripts/skf-promote-staged.py'
|
|
53
|
+
- '{project-root}/src/shared/scripts/skf-promote-staged.py'
|
|
54
|
+
# Resolve `{sourceTreeHelper}` to the first existing path. §7 removes the
|
|
55
|
+
# private tree step 3 read a remote source from; if neither path exists, the
|
|
56
|
+
# tree stays until a later run removes it, seven days on; every HARD HALT
|
|
57
|
+
# also closes the tree through it (Rules).
|
|
58
|
+
sourceTreeProbeOrder:
|
|
59
|
+
- '{project-root}/_bmad/skf/shared/scripts/skf-source-tree.py'
|
|
60
|
+
- '{project-root}/src/shared/scripts/skf-source-tree.py'
|
|
61
|
+
# HARD HALT helper (Rules).
|
|
62
|
+
emitEnvelopeProbeOrder:
|
|
63
|
+
- '{project-root}/_bmad/skf/shared/scripts/skf-emit-result-envelope.py'
|
|
64
|
+
- '{project-root}/src/shared/scripts/skf-emit-result-envelope.py'
|
|
18
65
|
---
|
|
19
66
|
|
|
20
67
|
<!-- Config: communicate in {communication_language}. -->
|
|
@@ -23,78 +70,76 @@ forgeTierRwProbeOrder:
|
|
|
23
70
|
|
|
24
71
|
## STEP GOAL:
|
|
25
72
|
|
|
26
|
-
To
|
|
73
|
+
To publish the staged skill byte for byte: the deliverables to `{skill_package}` and the workspace artifacts to `{forge_version}`, through one helper that creates the folders it needs. Then create or update the `active` symlink.
|
|
27
74
|
|
|
28
75
|
## Rules
|
|
29
76
|
|
|
30
|
-
-
|
|
31
|
-
- All base artifact types must be written (
|
|
32
|
-
-
|
|
77
|
+
- Generate only `extraction-rules.yaml` (§2): every other file is promoted as steps 5 to 6 left it in the staging folder, never written again from what context holds
|
|
78
|
+
- All base artifact types must be written (3 deliverables + N reference files + 3 workspace files)
|
|
79
|
+
- A HARD HALT, once step 3 §2b has bound `{source_tree}`, first runs `uv run {sourceTreeHelper} close --tree "{source_tree}"` from `{project-root}` (resolved from `{sourceTreeProbeOrder}`) and goes on whatever it prints, and emits through `{emitEnvelopeHelper}`, resolved from `{emitEnvelopeProbeOrder}` when it is not bound. After its envelope, under `--batch` it ends only this brief: return to `references/batch-mode.md` §3, even when the halt reads as the end of the run.
|
|
33
80
|
|
|
34
81
|
## MANDATORY SEQUENCE
|
|
35
82
|
|
|
36
|
-
### 1.
|
|
83
|
+
### 1. Check Ownership
|
|
37
84
|
|
|
38
|
-
|
|
85
|
+
`{name}` is the skill name from the brief (kebab-case). `{version}` is the working version: the brief's `version`, unless step 3's source resolution replaced it with `target_version` or the detected source version (`source-resolution-protocols.md` "Version Reconciliation"), with build metadata stripped per `knowledge/version-paths.md`.
|
|
39
86
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
{
|
|
44
|
-
{forge_version} # {forge_data_folder}/{name}/{version}/
|
|
87
|
+
**Ownership check.** Run it before creating any directory, `{forge_version}` included. Resolve `{skillInventoryHelper}` ← first existing path in `{skillInventoryProbeOrder}` and run:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
uv run {skillInventoryHelper} {skills_output_folder} --skill {name} --write-check --write-version {version} --forge-data-folder {forge_data_folder}
|
|
45
91
|
```
|
|
46
92
|
|
|
47
|
-
|
|
48
|
-
If `assets_inventory` is non-empty, also create: `{skill_package}/assets/`
|
|
93
|
+
`--forge-data-folder` only tells the helper whether both settings name one folder, so the brief and forge files there count as SKF output.
|
|
49
94
|
|
|
50
|
-
|
|
95
|
+
Bind `{write_verdict}` ← `write_check.verdict`, `{write_folder}` ← `write_check.folder`, `{write_detail}` ← `write_check.detail` and `{existing_generator}` ← `write_check.version_generated_by` (the build §3 replaces, for step 8; null when none). Continue only when the status is `ok` and `{write_verdict}` is `"ok"`: nothing is at the skill folder yet, it holds only what an interrupted run leaves, or SKF generated it and the version is new or SKF's own. Otherwise create nothing and refuse with the first case that applies:
|
|
51
96
|
|
|
52
|
-
|
|
97
|
+
- `{write_verdict}` is `"flat-layout"` → `halt_reason: "flat-layout"`: "**`{name}` still uses the flat layout — nothing was written.** A version written beside its root `SKILL.md` would leave a skill SKF can no longer migrate or rename. Run `@Ferris TS {name}` (or US, AS or EX) once to move it into the versioned layout, then re-run."
|
|
98
|
+
- `{write_verdict}` is `"not-skf-output"` → `halt_reason: "not-skf-output"`: "**`{name}` is not SKF output — nothing was written.** `{write_folder}` {write_detail}, so SKF will not write a version there. A shared `{skills_output_folder}` is supported: SKF leaves the skills it did not generate alone, so manage `{name}` yourself, and set a different `name` in the brief to create this skill beside it. Only if `{skills_output_folder}` holds a module's own source rather than skills, set `skills_output_folder` in `{project-root}/_bmad/skf/config.yaml` to a folder of its own, move your SKF skills there and re-run `/skf-setup`. A version folder with no `metadata.json` can also be one that an interrupted create-skill run left behind; delete it yourself in that case."
|
|
99
|
+
- The status is not `ok`, or the output has no `write_check` (an older helper: it has no `--write-check` and reports a new skill as `SKILL_NOT_FOUND`) → `halt_reason: "not-skf-output"`: the same message with "SKF could not check it ({the helper's `error`, if any}; re-install SKF if the installed `skf-skill-inventory.py` is out of date)" in place of "`{write_folder}` {write_detail}".
|
|
100
|
+
- When no helper candidate resolves, continue only when nothing exists at `{skill_group}` (no folder, no file, not even a broken link). Otherwise refuse with `halt_reason: "not-skf-output"` and the same message, giving "SKF cannot check who generated `{skill_group}`: `skf-skill-inventory.py` is missing; re-install SKF" in place of "`{write_folder}` {write_detail}".
|
|
53
101
|
|
|
54
|
-
|
|
102
|
+
Each refusal is a **HARD HALT** (exit code 5, `{halt_reason}`, phase `generate-artifacts`; stage `{run_dir}/halt.json` per the Workflow Rules and run `uv run {emitEnvelopeHelper} emit-halt --workflow skf-create-skill --run-dir "{run_dir}" --target stderr < "{run_dir}/halt.json"`), with the `halt_reason` shown and `{write_folder}` as `"path"`. Nothing was written, and the command leaves out `--result-dir`: a result file would land in a folder SKF refuses to write.
|
|
55
103
|
|
|
56
|
-
|
|
104
|
+
The folders this step writes:
|
|
57
105
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
106
|
+
```
|
|
107
|
+
{skill_group} # {skills_output_folder}/{name}/
|
|
108
|
+
{skill_package} # {skills_output_folder}/{name}/{version}/{name}/
|
|
109
|
+
{forge_version} # {forge_data_folder}/{name}/{version}/
|
|
110
|
+
```
|
|
62
111
|
|
|
63
|
-
|
|
64
|
-
- Compressed 2-line format for CLAUDE.md integration
|
|
112
|
+
The promotion (§3) creates them. An existing `{skill_package}` is replaced whole: the ownership check accepted it, and a package left half from an earlier compile of this version would mix two runs. Only its hand-written `[MANUAL]` content carries forward: its blocks are in the staged SKILL.md (step 5), and §3 carries its files.
|
|
65
113
|
|
|
66
|
-
|
|
67
|
-
- Machine-readable birth certificate with stats and provenance
|
|
114
|
+
### 2. Generate extraction-rules.yaml
|
|
68
115
|
|
|
69
|
-
|
|
70
|
-
- One file per function group or type
|
|
71
|
-
- Progressive disclosure detail files
|
|
116
|
+
`extraction-rules.yaml` records the language and the ast-grep rules this extraction used, for reproducibility, and it is the one file this step generates. `{extractionInventoryHelper}` writes it from the extraction inventory step 3 §5 wrote, `{extraction_inventory}` (`{project-root}/_bmad-output/.skf-stage/{skill-name}.inventory.json`): its `extraction_rules` (`recipe_set`, the `recipes` ids the runner ran, its `scope` and `ast_grep_version`), its `tier` and extraction mode, and the brief's `language`. Resolve `{extractionInventoryHelper}` ← first existing path in `{extractionInventoryProbeOrder}` and `{atomicWriteHelper}` ← first existing path in `{atomicWriteProbeOrder}` (§4's flip goes through it); if either has no path, **HARD HALT** (exit code 3, `helper-missing`, phase `generate-artifacts`; stage `{run_dir}/halt.json` per the Workflow Rules and run `uv run {emitEnvelopeHelper} emit-halt --workflow skf-create-skill --run-dir "{run_dir}" --target stderr < "{run_dir}/halt.json"`): "Cannot generate the artifacts: {the missing script} is missing. Re-install SKF, then re-run create-skill." From `{project-root}`, write it into the staging folder, so the promotion carries it with the rest:
|
|
72
117
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
118
|
+
```bash
|
|
119
|
+
uv run {extractionInventoryHelper} rules --inventory "{extraction_inventory}" --language "{brief.language}" --target "<staging-skill-dir>/extraction-rules.yaml"
|
|
120
|
+
```
|
|
76
121
|
|
|
77
|
-
**
|
|
78
|
-
- One file per detected asset, copied from source with content preserved
|
|
79
|
-
- Only created when `assets_inventory` is non-empty
|
|
122
|
+
When it exits non-zero, **HARD HALT** (exit code 4, `write-failed`, phase `generate-artifacts`; stage `{run_dir}/halt.json` per the Workflow Rules and run `uv run {emitEnvelopeHelper} emit-halt --workflow skf-create-skill --run-dir "{run_dir}" --target stderr < "{run_dir}/halt.json"`), with `"path"` the staged `extraction-rules.yaml`: "Cannot write extraction-rules.yaml: {the helper's message}. Check permissions and disk space." Nothing has been promoted yet.
|
|
80
123
|
|
|
81
|
-
|
|
124
|
+
### 3. Promote the Staged Skill
|
|
82
125
|
|
|
83
|
-
|
|
126
|
+
Resolve `{promoteStagedHelper}` ← first existing path in `{promoteStagedProbeOrder}`; if neither exists, **HARD HALT** (exit code 3, `helper-missing`, phase `generate-artifacts`; stage `{run_dir}/halt.json` per the Workflow Rules and run `uv run {emitEnvelopeHelper} emit-halt --workflow skf-create-skill --run-dir "{run_dir}" --target stderr < "{run_dir}/halt.json"`): "Cannot promote the staged skill: skf-promote-staged.py is missing. Re-install SKF, then re-run create-skill." From `{project-root}`, run:
|
|
84
127
|
|
|
85
|
-
|
|
128
|
+
```bash
|
|
129
|
+
uv run {promoteStagedHelper} promote --stage "<staging-skill-dir>" --package "{skill_package}" --forge-version "{forge_version}" [--inventory "{extraction_inventory}" --source-root "{source_root}"] [--carry-manual "{skill_package}"]
|
|
130
|
+
```
|
|
86
131
|
|
|
87
|
-
|
|
132
|
+
Pass `--inventory` and `--source-root` when the inventory's `scripts_inventory` or `assets_inventory` is not empty, and `--carry-manual "{skill_package}"` when `{skill_package}` already exists. The helper copies the staged bytes, never a copy from context:
|
|
88
133
|
|
|
89
|
-
**
|
|
90
|
-
-
|
|
134
|
+
- **To `{skill_package}`:** `SKILL.md`, `context-snippet.md`, `metadata.json` (with the `doc_sources` step 5a wrote into it) and every file under the staged `references/` (the `references/full-*.md` files step 5b extracted included), plus `scripts/{name}` and `assets/{name}` for each inventory script and asset, copied from `{source_root}`, and, with `--carry-manual`, the earlier build's `scripts/[MANUAL]/` and `assets/[MANUAL]/` files. The package is built beside its target and swapped in, so a reader never sees half of it.
|
|
135
|
+
- **To `{forge_version}`:** `{forge_version}/provenance-map.json`, `{forge_version}/evidence-report.md` and `{forge_version}/extraction-rules.yaml`, one atomic write each, and, with a warning, `{forge_version}/manual-backup/SKILL-<UTC time>.md` (the earlier SKILL.md, a new file each run) when the staged one lacks a hand-written `[MANUAL]` block of it.
|
|
136
|
+
- **Not copied:** a promoted authoritative doc (`file_entries[]` with `file_type: "doc"`, from step 3 §2a) stays at its source path; the provenance map tracks it for drift detection.
|
|
91
137
|
|
|
92
|
-
|
|
93
|
-
- Build artifact with extraction summary, validation results, warnings
|
|
138
|
+
Bind `{promotion}` ← its JSON: `files[]` (each promoted file's `path`, `kind`, `bytes` and `sha256`, read back and checked against the staged bytes), `counts`, `ignored` (staged files it did not promote), `manual` (what `--carry-manual` kept: `blocks`, `missing_blocks`, `files`, `backup`) and `warnings`; display each warning. Act on its exit code:
|
|
94
139
|
|
|
95
|
-
**
|
|
96
|
-
-
|
|
97
|
-
-
|
|
140
|
+
- **0:** continue to §4.
|
|
141
|
+
- **1** (a staged file it needs is missing, the inventory names a script or asset it cannot copy, or the earlier package cannot be read; nothing was written): **HARD HALT** (exit code 4, `staging-unreadable`, phase `generate-artifacts`; stage `{run_dir}/halt.json` per the Workflow Rules and run `uv run {emitEnvelopeHelper} emit-halt --workflow skf-create-skill --run-dir "{run_dir}" --result-dir "{forge_version}" --target stderr < "{run_dir}/halt.json"`), with the message the helper printed on stderr.
|
|
142
|
+
- **2** (a write failed; the earlier package stays in place when the swap itself failed): **HARD HALT** (exit code 4, `write-failed`, phase `generate-artifacts`; stage `{run_dir}/halt.json` per the Workflow Rules and run `uv run {emitEnvelopeHelper} emit-halt --workflow skf-create-skill --run-dir "{run_dir}" --result-dir "{forge_version}" --target stderr < "{run_dir}/halt.json"`): "Artifact generation failed: {the message the helper printed on stderr}. Check permissions and disk space." Once the swap succeeded, stage `"skill_package"` and `"outputs"` as the Workflow Rules say.
|
|
98
143
|
|
|
99
144
|
### 4. Create Active Symlink (atomic flip)
|
|
100
145
|
|
|
@@ -106,28 +151,15 @@ python3 {atomicWriteHelper} flip-link \
|
|
|
106
151
|
--target {version}
|
|
107
152
|
```
|
|
108
153
|
|
|
109
|
-
The helper returns non-zero (exit 2) if `{skill_group}/active` already exists as a real directory or file rather than a symlink
|
|
154
|
+
The helper returns non-zero (exit 2) if `{skill_group}/active` already exists as a real directory or file rather than a symlink. In that case **HARD HALT** (exit code 5, `active-link-blocked`, phase `generate-artifacts`; stage `{run_dir}/halt.json` per the Workflow Rules and run `uv run {emitEnvelopeHelper} emit-halt --workflow skf-create-skill --run-dir "{run_dir}" --result-dir "{forge_version}" --target stderr < "{run_dir}/halt.json"`), with `"skill_package"`, `"outputs"` and `{skill_group}/active` as `"path"`: "Refusing to flip `{skill_group}/active`: the existing path is not a symlink. Investigate manually; expected a symlink pointing at a version directory."
|
|
110
155
|
|
|
111
156
|
Do not `rm` + `ln -s` the active link by hand. The bare-rm pattern has two failure modes: (1) a concurrent reader sees a missing `active` mid-flip, and (2) a bug or typo that replaces `{skill_group}/active` with a plain directory turns the next manual `rm -rf {skill_group}/active` into data loss. The helper encapsulates both guards.
|
|
112
157
|
|
|
113
158
|
### 5. Verify Write Completion
|
|
114
159
|
|
|
115
|
-
|
|
116
|
-
- All 4 deliverable artifact types exist (SKILL.md, context-snippet.md, metadata.json, **and** either at least one file in `references/` **or** `references/` is empty AND Tier-2 content is inline in SKILL.md — see "Empty `references/` exception" below), all 3 workspace artifacts exist (provenance-map.json, evidence-report.md, extraction-rules.yaml), plus scripts/ and assets/ files when inventories are non-empty
|
|
117
|
-
- The `active` symlink at `{skill_group}/active` resolves to `{version}`
|
|
118
|
-
- Store `ref_count` = count of files written to `references/` for use in step 8 report
|
|
119
|
-
- List each file with its path and size
|
|
160
|
+
The promotion's exit 0 is the write check: it refused a missing staged file, script or asset before writing (§3, exit 1) and read back every file it wrote against the staged bytes (exit 2 on a mismatch), and the flip's exit 0 (§4) means `{skill_group}/active` points at `{version}`. From `{promotion}`, bind `ref_count` ← `counts.references` for the step 8 report, and list each file of its `files[]` with its `path` and `bytes`.
|
|
120
161
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
```
|
|
124
|
-
ref_count: 0 # Tier-2 kept inline in SKILL.md (no split performed in step 6)
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
When `ref_count > 0` is expected (because step 6 ran a split) but no files were written, halt with: "Split-body produced zero reference files. Investigate step 6 output before retrying — empty `references/` after a split is never a valid state."
|
|
128
|
-
|
|
129
|
-
**If any write failed:**
|
|
130
|
-
Halt with: "Artifact generation failed: could not write `{file_path}`. Check permissions and disk space."
|
|
162
|
+
`ref_count` 0 is a valid state when step 6 kept Tier-2 content inline (its evidence report says so on the Body line). When step 5b or step 6 split the body (`sections_extracted` is not empty) and `ref_count` is 0 anyway, **HARD HALT** (exit code 5, `references-missing`, phase `generate-artifacts`; stage `{run_dir}/halt.json` per the Workflow Rules and run `uv run {emitEnvelopeHelper} emit-halt --workflow skf-create-skill --run-dir "{run_dir}" --result-dir "{forge_version}" --target stderr < "{run_dir}/halt.json"`), with `"skill_package"` and `"outputs"`: "Split-body produced zero reference files. Investigate step 6 output before retrying: empty `references/` after a split is never a valid state."
|
|
131
163
|
|
|
132
164
|
**If all writes succeeded:**
|
|
133
165
|
Display brief confirmation:
|
|
@@ -157,32 +189,32 @@ Proceeding to compilation report..."
|
|
|
157
189
|
|
|
158
190
|
Index the generated skill artifacts into a QMD collection so that audit-skill and update-skill can perform high-signal searches against curated extraction data instead of raw source files.
|
|
159
191
|
|
|
160
|
-
|
|
192
|
+
Resolve `{forgeTierRwHelper}` from `{forgeTierRwProbeOrder}`; first existing path wins. Every registry change below goes through it: it holds `{sidecar_path}/forge-tier.yaml.lock` for its one read-modify-write of `{forgeTierConfig}`, so no step takes a lock of its own. If no candidate exists, warn "forge-tier.yaml registry not updated: skf-forge-tier-rw.py is missing; re-install SKF" and leave out every registry command below.
|
|
193
|
+
|
|
194
|
+
**Collection creation:** Create (or replace) a QMD collection from the skill artifacts. When `qmd collection add` fails after the `remove`, the collection is gone from QMD, so its registry entry goes too:
|
|
195
|
+
|
|
161
196
|
```bash
|
|
162
197
|
qmd collection remove {name}-extraction 2>/dev/null # no-op if new
|
|
163
|
-
qmd collection add {skill_package} --name {name}-extraction --mask "**/*"
|
|
164
|
-
qmd embed --collection {name}-extraction
|
|
198
|
+
if qmd collection add {skill_package} --name {name}-extraction --mask "**/*"; then
|
|
199
|
+
qmd embed --collection {name}-extraction
|
|
200
|
+
else
|
|
201
|
+
uv run {forgeTierRwHelper} remove-qmd-collection --target "{forgeTierConfig}" --name {name}-extraction
|
|
202
|
+
fi
|
|
165
203
|
```
|
|
166
204
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
Read `{forgeTierConfig}` and update the `qmd_collections` array **under an exclusive `flock` on `{sidecar_path}/forge-tier.yaml.lock`** (see step 3b §4 for the full pattern — acquire lock → read → modify → atomic write via `skf-atomic-write.py write` → release). If `flock` is unavailable, fall back to read-CAS-by-mtime.
|
|
205
|
+
`qmd embed` generates the vector embeddings for semantic (`vec`) and HyDE query sub-types; scope it to this collection to avoid re-embedding others. If the installed qmd CLI lacks `--collection`, gate the embed behind a per-skill freshness check: read the registry with `uv run {forgeTierRwHelper} read --target "{forgeTierConfig}"`, skip the embed when the `{name}-extraction` entry in its `data.qmd_collections` was created within the last 24 hours, and warn in evidence-report. An unscoped embed re-runs over every collection, which in a populated QMD store can cost minutes of GPU time per create-skill run; 24 hours is long enough to absorb rapid re-forges from the same brief without losing meaningful content freshness.
|
|
170
206
|
|
|
171
|
-
|
|
207
|
+
**Registry update:** only when `qmd collection add` succeeded, register the collection. The helper replaces the entry with the same `name`, or appends one:
|
|
172
208
|
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
skill_name: "{name}"
|
|
178
|
-
created_at: "{current ISO date}"
|
|
209
|
+
```bash
|
|
210
|
+
uv run {forgeTierRwHelper} register-qmd-collection --target "{forgeTierConfig}" <<'SKF_REGISTRY_ENTRY'
|
|
211
|
+
{"name": "{name}-extraction", "type": "extraction", "source_workflow": "create-skill", "skill_name": "{name}", "created_at": "{current ISO date}"}
|
|
212
|
+
SKF_REGISTRY_ENTRY
|
|
179
213
|
```
|
|
180
214
|
|
|
181
|
-
Write the updated forge-tier.yaml.
|
|
182
|
-
|
|
183
215
|
**Error handling:**
|
|
184
216
|
- If QMD collection creation fails: log the error, note that indexing can be retried via [SF] setup. Do not fail the workflow.
|
|
185
|
-
- If
|
|
217
|
+
- If a registry command fails: log the error, continue. The collection exists in QMD even if the registry entry failed.
|
|
186
218
|
|
|
187
219
|
**IF forge tier is not Deep:** Skip this section silently. No messaging.
|
|
188
220
|
|
|
@@ -190,36 +222,56 @@ Write the updated forge-tier.yaml.
|
|
|
190
222
|
|
|
191
223
|
**IF `tools.ccc` is true in forge-tier.yaml (Forge+ or Deep with ccc available):**
|
|
192
224
|
|
|
193
|
-
Ensure the source
|
|
225
|
+
Ensure the source of this skill is indexed by ccc and registered in the `ccc_index_registry` array.
|
|
226
|
+
|
|
227
|
+
**Pick the folder:** bind `{ccc_root}`, the folder the index belongs to, and `{ccc_settings_owner}`:
|
|
228
|
+
|
|
229
|
+
- **Docs-only skill** (`source_type: "docs-only"`): there is no source to index. Skip the rest of this section.
|
|
230
|
+
- **Remote source** (`source_repo` is a GitHub URL, an `owner/repo` shorthand or another git URL): the index belongs in SKF's workspace clone, which persists, and not in the tree step 3 read the source from, which §7 removes. When step 3 bound `{remote_clone_path}`, the clone holds `source_commit`: bind `{ccc_root}` ← `{remote_clone_path}` and `{ccc_settings_owner}` ← `skf`. When it left `{remote_clone_path}` null (Quick tier, a run step 3 degraded to source reading, or a clone it did not move to this skill's commit), skip the rest of this section, including the registry update.
|
|
231
|
+
- **Local source:** bind `{ccc_root}` ← `{source_root}` and `{ccc_settings_owner}` ← `user`.
|
|
194
232
|
|
|
195
233
|
**Index verification:**
|
|
196
234
|
|
|
197
|
-
**Working-directory contract:** `ccc init`, `ccc index`, and `ccc status` take **no positional path argument
|
|
235
|
+
**Working-directory contract:** `ccc init`, `ccc index`, and `ccc status` take **no positional path argument**: each operates on the current working directory, and passing a path makes them exit non-zero with `Got unexpected extra argument`. Run them from `{ccc_root}` (`cd "{ccc_root}" && ccc …`, the same form `extract.md` step 2b and `knowledge/ccc-bridge.md` use), then return to `{project-root}` before the registry update below, which resolves `{forgeTierConfig}` relative to the project.
|
|
236
|
+
|
|
237
|
+
**Project root without settings:** check this before running any ccc command. When `{ccc_root}` is `{project-root}` and `{project-root}/.cocoindex_code/settings.yml` does not exist, do not run `ccc init` or `ccc index`: `/skf-setup` initializes the project index with the SKF exclusions, and in a project nested inside another git checkout `ccc index` would index the enclosing repository instead. Skip the rest of this section, including the registry update, note that re-running `/skf-setup` enables the index, and continue to §7.
|
|
238
|
+
|
|
239
|
+
Otherwise, `ccc index` requires the directory to be initialized first:
|
|
240
|
+
|
|
241
|
+
- `{ccc_settings_owner}` `skf`: resolve `{mergeCccExclusionsHelper}` from `{mergeCccExclusionsProbeOrder}` and, from `{project-root}`, run `uv run {mergeCccExclusionsHelper} --clone-root "{ccc_root}"`. It runs `ccc init -f` in the clone when its `settings.yml` is missing and adds the standard build and dependency exclusions the file lacks, as step 3 §2b does, so it changes nothing once step 3 prepared the clone. When no candidate resolves, the command fails or `settings_ready` is false, log it and skip the rest of this section, including the registry update.
|
|
242
|
+
- `{ccc_settings_owner}` `user`: run `cd "{ccc_root}" && ccc init` (idempotent: a no-op once initialized).
|
|
243
|
+
|
|
244
|
+
Then run `cd "{ccc_root}" && ccc index`, or use the ccc MCP tool. `ccc_bridge.ensure_index` is a conceptual interface, not a callable function. Indexing is a no-op if the source was already indexed during setup, step 2b or step 3.
|
|
245
|
+
|
|
246
|
+
**Nested project marker:** when `{ccc_root}` is a local source inside a git checkout whose `.git` is a folder, or inside a folder that holds `.cocoindex_code/settings.yml` (a local source such as `./packages/lib`, or a linked worktree or submodule inside such a checkout, whose `.git` file ccc does not count as a marker), `ccc init` exits non-zero with `A parent directory has a project marker`. This is expected: re-run as `cd "{ccc_root}" && ccc init -f` to initialize at the subtree anyway, then `ccc index`. Do not treat the parent-marker warning as fatal. ccc writes no `.gitignore` entry for such a project; **Keep the index out of git** below covers it.
|
|
198
247
|
|
|
199
|
-
`ccc index
|
|
248
|
+
**Verify the index is not degraded:** after `ccc index`, load `{cccIndexCheckData}` and run it with `{ccc_root}` and `{ccc_settings_owner}`. An index that misses the source language silently cripples later `skf-audit-skill` / `skf-update-skill` searches with no error surfaced. On **index unverified**, log "index unverified" and continue with **Keep the index out of git**. On **degraded**, log it and continue per the error handling below: a degraded index is not workflow-fatal, but it must be recorded so the gap is visible.
|
|
200
249
|
|
|
201
|
-
**
|
|
250
|
+
**Keep the index out of git:** once the ccc commands above are done (after the check, after "index unverified", or after a ccc command failed), return to `{project-root}` and resolve `{cccGitHygieneHelper}` from `{cccGitHygieneProbeOrder}`; first existing path wins. If no candidate exists, or the helper exits non-zero or prints no JSON, log "ccc git hygiene skipped" and continue to the registry update: this check never fails the workflow.
|
|
202
251
|
|
|
203
|
-
**
|
|
252
|
+
- **Workspace clone** (`{ccc_settings_owner}` is `skf`): run `uv run {cccGitHygieneHelper} workspace --repo "{ccc_root}"`. It undoes the edit a `ccc init` or `ccc index` made to the clone's tracked `.gitignore` and keeps the index folder out of git through the clone's `.git/info/exclude`, so a later move of the clone to another ref is not blocked. Read nothing from its output.
|
|
253
|
+
- **Local source** (`{ccc_settings_owner}` is `user`): run `uv run {cccGitHygieneHelper} nested --dir "{ccc_root}" --project-root "{project-root}"`. ccc gitignores its index only at the top of a git checkout whose `.git` is a folder, so for a project in a subfolder of a checkout (the `ccc init -f` case above), a linked worktree or a submodule, `git status` lists the index database and a `git add -A` would commit it. When git does not ignore `{ccc_root}/.cocoindex_code/`, the helper writes a `.gitignore` holding `*` inside that folder so the folder ignores itself; SKF never edits a project's own `.gitignore`. It also repairs a nested index an earlier run left, and does nothing for `{project-root}` itself, for a folder without `.cocoindex_code/settings.yml`, or outside a git work tree. Bind `{ccc_ignore_notice}` ← `notice` and display `{ccc_ignore_notice}` verbatim when it is not null: its remedy command is quoted for paths with spaces.
|
|
204
254
|
|
|
205
255
|
**Registry update:**
|
|
206
256
|
|
|
207
|
-
**Resolve `{forgeTierRwHelper}`** from `{forgeTierRwProbeOrder}`; first existing path wins.
|
|
257
|
+
**Resolve `{forgeTierRwHelper}`** from `{forgeTierRwProbeOrder}`; first existing path wins. If no candidate exists, log it and skip the registry update.
|
|
208
258
|
|
|
209
|
-
Register the indexed
|
|
259
|
+
Register the indexed folder with `register-ccc-index`, a comment-preserving round-trip on `forge-tier.yaml` that keeps the `ccc_index_registry` deduplication in the script. Like every registry change of §6, the helper holds `{sidecar_path}/forge-tier.yaml.lock` for its one read-modify-write. Write `{ccc_root}` with `/` separators, so the JSON stays valid on Windows:
|
|
210
260
|
|
|
211
261
|
```bash
|
|
212
|
-
|
|
213
|
-
|
|
262
|
+
uv run {forgeTierRwHelper} register-ccc-index --target "{forgeTierConfig}" <<'SKF_REGISTRY_ENTRY'
|
|
263
|
+
{"source_repo": "{brief.source_repo}", "path": "{ccc_root}", "skill_name": "{name}", "indexed_at": "{current ISO date}", "source_workflow": "create-skill"}
|
|
264
|
+
SKF_REGISTRY_ENTRY
|
|
214
265
|
```
|
|
215
266
|
|
|
216
|
-
Deduplicates by `source_repo` + `skill_name
|
|
267
|
+
Deduplicates by `source_repo` + `skill_name`, not by the local `path`.
|
|
217
268
|
|
|
218
|
-
**Error handling:** If ccc indexing or registry update fails, log and continue
|
|
269
|
+
**Error handling:** If ccc indexing or registry update fails, log and continue: do not fail the workflow.
|
|
219
270
|
|
|
220
271
|
**IF `tools.ccc` is false:** Skip this section silently.
|
|
221
272
|
|
|
222
273
|
### 7. Auto-Proceed
|
|
223
274
|
|
|
224
|
-
|
|
275
|
+
**Remove the private source tree.** When step 3 bound `{source_tree}`, no later step reads the source: resolve `{sourceTreeHelper}` from `{sourceTreeProbeOrder}` and, from `{project-root}`, run `uv run {sourceTreeHelper} close --tree "{source_tree}"`. Go on whatever it prints. On `left` or `refused`, a command that fails or prints no JSON, or no candidate, display "This run's source tree `{source_tree}` was not removed; a later SKF run removes it once it is seven days old." Then set `{source_tree}` to null.
|
|
225
276
|
|
|
277
|
+
No user interaction. Once the skill is promoted and verified (and optionally indexed into QMD), load `{nextStepFile}`, read it fully, then execute it. A QMD-indexing failure does not block; a promotion failure halts (§3) rather than proceeding with partial output.
|
|
@@ -17,7 +17,7 @@ Chain to the shared workflow self-improvement health check at `{nextStepFile}`.
|
|
|
17
17
|
|
|
18
18
|
- No user-facing reports, file writes, or result contracts in this step — those belong in step 8
|
|
19
19
|
- Delegate directly to `{nextStepFile}` with no additional commentary
|
|
20
|
-
-
|
|
20
|
+
- Under `--batch`, `references/batch-mode.md` §4 loads this step once, after the batch summary; report.md §6 sends each brief back to batch-mode.md §3 instead of here
|
|
21
21
|
- Do not attempt any other action between loading this step and executing `{nextStepFile}`
|
|
22
22
|
|
|
23
23
|
## MANDATORY SEQUENCE
|