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,177 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
nextStepFile: 'report.md'
|
|
3
|
-
outputFile: '{forge_version}/drift-report-{timestamp}.md'
|
|
4
|
-
# Resolve `{compareDocHashesHelper}` by probing `{compareDocHashesProbeOrder}`
|
|
5
|
-
# in order (installed SKF module path first, src/ dev-checkout fallback); first
|
|
6
|
-
# existing path wins. When neither resolves (uv/python absent), §2 falls back to
|
|
7
|
-
# skipping the doc-drift check with a notice — see the graceful-failure rule.
|
|
8
|
-
compareDocHashesProbeOrder:
|
|
9
|
-
- '{project-root}/_bmad/skf/shared/scripts/skf-detect-docs.py'
|
|
10
|
-
- '{project-root}/src/shared/scripts/skf-detect-docs.py'
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
<!-- Config: communicate in {communication_language}. -->
|
|
14
|
-
|
|
15
|
-
# Step 5a: Documentation Drift
|
|
16
|
-
|
|
17
|
-
## STEP GOAL:
|
|
18
|
-
|
|
19
|
-
Compare documentation content hashes stored at compile time (in `doc_sources` within metadata.json) against the current upstream state. Produce a drift section that reports which tracked docs have changed, which are unreachable, and which were never hashed. This step is informational — doc drift does not affect the source code drift score.
|
|
20
|
-
|
|
21
|
-
## Rules
|
|
22
|
-
|
|
23
|
-
- Auto-proceed step — no user interaction
|
|
24
|
-
- Graceful failure — if doc fetching fails for any URL, mark as `fetch_failed`, do not block the audit
|
|
25
|
-
- Do not classify severity — doc drift is informational alongside source drift
|
|
26
|
-
- If no `doc_sources` in metadata, skip with notice and auto-proceed
|
|
27
|
-
- Never abort the audit pipeline on any failure in this step
|
|
28
|
-
|
|
29
|
-
## MANDATORY SEQUENCE
|
|
30
|
-
|
|
31
|
-
### 1. Check for doc_sources
|
|
32
|
-
|
|
33
|
-
Check the skill metadata loaded at init (step 1 §3 — Load Skill Artifacts) for a `doc_sources` array.
|
|
34
|
-
|
|
35
|
-
**If `doc_sources` is absent or metadata lacks the field:**
|
|
36
|
-
|
|
37
|
-
Append to {outputFile}:
|
|
38
|
-
|
|
39
|
-
```markdown
|
|
40
|
-
## Documentation Drift
|
|
41
|
-
|
|
42
|
-
No doc_sources recorded — skip doc drift check. This skill was compiled before doc tracking was available. Recompile with the current CS pipeline to enable doc drift detection.
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
Set `doc_drift_summary = { skipped_entirely: true }` in workflow context. Update {outputFile} frontmatter: append `'doc-drift'` to `stepsCompleted`. Auto-proceed to {nextStepFile}.
|
|
46
|
-
|
|
47
|
-
**If `doc_sources` is present but an empty array:**
|
|
48
|
-
|
|
49
|
-
Append to {outputFile}:
|
|
50
|
-
|
|
51
|
-
```markdown
|
|
52
|
-
## Documentation Drift
|
|
53
|
-
|
|
54
|
-
No documentation sources tracked. The `doc_sources` array is empty — no drift check to perform.
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
Set `doc_drift_summary = { total_tracked: 0, skipped_entirely: false }` in workflow context. Update {outputFile} frontmatter: append `'doc-drift'` to `stepsCompleted`. Auto-proceed to {nextStepFile}.
|
|
58
|
-
|
|
59
|
-
**If `doc_sources` is present and non-empty:** Continue to §2.
|
|
60
|
-
|
|
61
|
-
### 2. Fetch and Hash Each Tracked Doc
|
|
62
|
-
|
|
63
|
-
Fetching each URL, hashing the response bytes, comparing against the stored `content_hash`, and categorizing the outcome is deterministic work — and the model cannot compute a `sha256:{hexdigest}` of fetched bytes natively (it must shell out). Delegate the whole fetch/hash/compare pass to the shared script, which hashes byte-symmetrically with how `doc_sources` hashes were written at compile time and fetches independently of whether a WebFetch tool is wired.
|
|
64
|
-
|
|
65
|
-
**Resolve `{compareDocHashesHelper}`** from `{compareDocHashesProbeOrder}`; first existing path wins.
|
|
66
|
-
|
|
67
|
-
Run one deterministic comparison subprocess over the skill's `doc_sources`. The script reads the `doc_sources` array straight out of the skill's `metadata.json` (or accepts a bare `doc_sources` array, or `-` for stdin):
|
|
68
|
-
|
|
69
|
-
```bash
|
|
70
|
-
uv run {compareDocHashesHelper} compare-hashes {skill_path}/metadata.json
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
For each entry, the script:
|
|
74
|
-
- **`content_hash` is `null`** → records it under `skipped_null_hash` and does **not** fetch the URL (there is no baseline to compare against).
|
|
75
|
-
- **`content_hash` is non-null** → HTTP GETs the URL (15s timeout, same User-Agent as the compile side), computes `sha256:{hexdigest}` of the response body bytes, and compares against the stored `content_hash` (prefix-normalized so a bare-hex writer form still matches).
|
|
76
|
-
- Hashes match → `unchanged`.
|
|
77
|
-
- Hashes differ → `changed`, carrying `old_hash` and `new_hash`.
|
|
78
|
-
- Network error, timeout, or non-200 status → `fetch_failed`, carrying the failure `reason`. Not reported as drift.
|
|
79
|
-
|
|
80
|
-
Parse the emitted JSON:
|
|
81
|
-
|
|
82
|
-
```json
|
|
83
|
-
{
|
|
84
|
-
"changed": [{"url": "...", "old_hash": "sha256:...", "new_hash": "sha256:..."}],
|
|
85
|
-
"unchanged": [{"url": "..."}],
|
|
86
|
-
"fetch_failed": [{"url": "...", "old_hash": "sha256:...", "reason": "..."}],
|
|
87
|
-
"skipped_null_hash": [{"url": "..."}],
|
|
88
|
-
"stats": {"total_tracked": N, "changed": N, "unchanged": N, "fetch_failed": N, "skipped_null_hash": N}
|
|
89
|
-
}
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
The script exits 0 on any well-formed input (even when everything drifted) and exits 2 only on malformed args/JSON — it never blocks this informational audit.
|
|
93
|
-
|
|
94
|
-
If `uv`/`python` is unavailable or the script cannot be resolved — i.e. URL fetching is unavailable in the current environment — skip the doc drift check entirely with:
|
|
95
|
-
|
|
96
|
-
```markdown
|
|
97
|
-
## Documentation Drift
|
|
98
|
-
|
|
99
|
-
Doc drift check skipped — URL fetching unavailable in current environment.
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
Set `doc_drift_summary = { skipped_entirely: true }` and auto-proceed.
|
|
103
|
-
|
|
104
|
-
### 3. Build Drift Findings
|
|
105
|
-
|
|
106
|
-
Read the categories and totals directly from the script's JSON — no manual counting. The four buckets are already computed:
|
|
107
|
-
- **changed:** entries where the stored `content_hash` differs from the newly computed hash (`changed[]`)
|
|
108
|
-
- **unchanged:** entries where the hashes match (`unchanged[]`)
|
|
109
|
-
- **fetch_failed:** entries where the URL could not be reached (`fetch_failed[]`)
|
|
110
|
-
- **skipped_null_hash:** entries where `content_hash` was `null` (`skipped_null_hash[]`)
|
|
111
|
-
|
|
112
|
-
Take the totals straight from `stats` (do not recount):
|
|
113
|
-
- `total_tracked` = `stats.total_tracked`
|
|
114
|
-
- `changed` = `stats.changed`
|
|
115
|
-
- `unchanged` = `stats.unchanged`
|
|
116
|
-
- `fetch_failed` = `stats.fetch_failed`
|
|
117
|
-
- `skipped_null_hash` = `stats.skipped_null_hash`
|
|
118
|
-
|
|
119
|
-
### 4. Append to Drift Report
|
|
120
|
-
|
|
121
|
-
Append the `## Documentation Drift` section to {outputFile}.
|
|
122
|
-
|
|
123
|
-
**When drift detected:**
|
|
124
|
-
|
|
125
|
-
```markdown
|
|
126
|
-
## Documentation Drift
|
|
127
|
-
|
|
128
|
-
| URL | Old Hash | New Hash | Detected At |
|
|
129
|
-
|-----|----------|----------|-------------|
|
|
130
|
-
| {url} | `{old_hash}` | `{new_hash}` | {ISO-8601 timestamp} |
|
|
131
|
-
|
|
132
|
-
**{changed} of {total_tracked} tracked documentation source(s) have changed since compile.**
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
Include rows for ALL entries, in order:
|
|
136
|
-
- Drifted entries: show old and new hash
|
|
137
|
-
- Unchanged entries: omit from table (only drifted entries appear)
|
|
138
|
-
- Fetch-failed entries: `| {url} | \`{old_hash}\` | _(fetch failed: {reason})_ | {timestamp} |`
|
|
139
|
-
- Null-hash entries: `| {url} | _(not recorded)_ | — | — |`
|
|
140
|
-
|
|
141
|
-
Fetch-failed entries are clearly marked and excluded from the drift count.
|
|
142
|
-
|
|
143
|
-
**When no drift detected:**
|
|
144
|
-
|
|
145
|
-
```markdown
|
|
146
|
-
## Documentation Drift
|
|
147
|
-
|
|
148
|
-
No documentation drift detected. All {total_tracked} tracked documentation source(s) match their compile-time hashes.
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
If some entries were fetch_failed or skipped_null_hash, append a note after the main message listing those entries.
|
|
152
|
-
|
|
153
|
-
### 5. Store Context and Auto-Proceed
|
|
154
|
-
|
|
155
|
-
Store `doc_drift_summary` in workflow context for report.md to reference:
|
|
156
|
-
|
|
157
|
-
```
|
|
158
|
-
doc_drift_summary = {
|
|
159
|
-
total_tracked: N,
|
|
160
|
-
changed: N,
|
|
161
|
-
unchanged: N,
|
|
162
|
-
fetch_failed: N,
|
|
163
|
-
skipped_null_hash: N,
|
|
164
|
-
skipped_entirely: false
|
|
165
|
-
}
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
Update {outputFile} frontmatter:
|
|
169
|
-
- Append `'doc-drift'` to `stepsCompleted`
|
|
170
|
-
|
|
171
|
-
Display: "**Documentation drift check complete. {changed} of {total_tracked} source(s) drifted. Proceeding to report generation...**"
|
|
172
|
-
|
|
173
|
-
Load, read the full file, then execute {nextStepFile}.
|
|
174
|
-
|
|
175
|
-
## CRITICAL STEP COMPLETION NOTE
|
|
176
|
-
|
|
177
|
-
Only when the ## Documentation Drift section has been appended to {outputFile} and workflow context updated do you then load and read fully `{nextStepFile}` to begin final report generation.
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
# Headless Source-Authority Detection
|
|
2
|
-
|
|
3
|
-
Loaded by step 1 §8 only when **all three** preconditions hold:
|
|
4
|
-
|
|
5
|
-
1. `{headless_mode}` is true
|
|
6
|
-
2. `source_authority` is absent from the validator's `normalized` output (the validator intentionally leaves it absent so detection can run here — when it was supplied in args, the supplied value wins and detection does not run)
|
|
7
|
-
3. `source_type=source` AND `target_repo` is a GitHub URL
|
|
8
|
-
|
|
9
|
-
When any precondition is unmet, skip this entire procedure: docs-only forces `community` in §3.2; local-path targets default to `community` directly; non-GitHub source URLs are not classifiable from `gh api user` and also default to `community`.
|
|
10
|
-
|
|
11
|
-
## Procedure
|
|
12
|
-
|
|
13
|
-
Probe the operator's GitHub login:
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
gh api user --jq .login
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
Compare the result to the `owner` segment of `target_repo` (URL pattern `https://github.com/<owner>/<repo>`) — **lower-case both values before comparing**. GitHub owner matching is case-insensitive but the API preserves case in responses, so a literal-string comparison would miss the match.
|
|
20
|
-
|
|
21
|
-
| Outcome | Set | Rationale |
|
|
22
|
-
|---------|-----|-----------|
|
|
23
|
-
| login matches owner (case-insensitive) | `source_authority: "official"` | The operator is the repo's GitHub owner |
|
|
24
|
-
| login does not match | `source_authority: "community"` | The operator is a downstream consumer |
|
|
25
|
-
| `gh api user` errors (unauthenticated, network failure, missing binary) | `source_authority: "community"` (fallback) | Log `"warn: source-authority detection skipped — gh api user failed"` |
|
|
26
|
-
| Local-path target | `source_authority: "community"` (no probe) | Comparison does not apply |
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
code: CA
|
|
2
|
-
name: skf-campaign
|
|
3
|
-
description: "Campaign orchestration — multi-library skill production with dependency tracking"
|
|
4
|
-
version: "2.0.0"
|
|
5
|
-
trigger: campaign
|
|
6
|
-
parent_module: skf
|
|
7
|
-
|
|
8
|
-
# Canonical internal filenames for the campaign workspace. Fixed contract (the
|
|
9
|
-
# step chain references these names directly and test-skf-campaign-state guards
|
|
10
|
-
# them against drift) — NOT an operator-override surface; customize.toml is the
|
|
11
|
-
# only customization mechanism.
|
|
12
|
-
config:
|
|
13
|
-
state_file: "_campaign-state.yaml"
|
|
14
|
-
backup_file: "_campaign-state.yaml.bak"
|
|
15
|
-
directive_file: "_campaign-directive.md"
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
# tessl Dismissal Rules
|
|
2
|
-
|
|
3
|
-
This file is the **single source of truth** for tessl review findings that Skill Forge expects and must dismiss. Step-06 §6 loads this file, parses the `tessl skill review` JSON output, and cross-references each finding against the rules below. Matches are dismissed with their rationale logged to the evidence report; non-matches surface to the user via §6b. Never embed dismissal logic in step files — update the rules here first and reference them from step 6.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Score Thresholds
|
|
8
|
-
|
|
9
|
-
When parsing tessl output, check these fields against the thresholds below. Violations trigger warnings or errors as specified.
|
|
10
|
-
|
|
11
|
-
| Field | Threshold | Severity on violation | Rationale |
|
|
12
|
-
|---|---|---|---|
|
|
13
|
-
| `review_score` (overall) | `>= 60` | warn | Two-tier SKF skills trade some conciseness score for progressive disclosure. 60 is the floor below which something is genuinely wrong. |
|
|
14
|
-
| `description_field` validator finding | none expected | **error — recover, then halt** | The **deterministic** `description_field` validator surfaces as a `findings[]` entry (not as the judge percentage). It parses the frontmatter `description` as a raw string and rejects angle-bracket / XML-tag content. step 5 §2a unconditionally replaces `<` with `{` and `>` with `}` before validation, so a `description_field` finding means the sanitizer was bypassed — a downstream tool rewrote the description. Attempt recovery per rule `description-xml-tags-guarded-upstream` (re-apply the §2a substitution in place on the staging SKILL.md frontmatter and re-run tessl). Halt only if recovery fails. |
|
|
15
|
-
| `description_score` (LLM judge %) | `>= 60` | warn | The judge's 0–100 discoverability score, composed of `trigger_term_quality`, `specificity`, `completeness`, and `distinctiveness` sub-scores. A value below 100 while the deterministic `description_field` validator PASSES is a soft discoverability hint (e.g. jargon density), **not** a sanitizer bypass — record a warning and continue. Never halt on the judge percentage alone; the authored brief is the source of truth for the description. |
|
|
16
|
-
| `content_score` | `>= 60` | warn | Two-tier design deliberately duplicates key API data across Tier 1 and Tier 2. Conciseness scorer penalizes this. 60 is the acceptable floor. |
|
|
17
|
-
|
|
18
|
-
**Recovery is gated on the deterministic validator, not the judge percentage.** If tessl emits a `findings[]` entry with rule ID `description_field` (angle-bracket / XML-tag rejection), **attempt recovery first** per rule `description-xml-tags-guarded-upstream` below: re-apply step 5 §2a's `<` → `{` / `>` → `}` substitution in place on the staging SKILL.md frontmatter `description`, then re-run `npx -y tessl skill review <staging-skill-dir>` once. If the re-run clears the `description_field` finding, log `description-recovery: applied ({count} substitutions)` in the evidence report and proceed to normal suggestion handling. If recovery fails, halt with: "Description sanitization recovery failed — step 5 §2a's `<`/`>` → `{`/`}` replacement did not resolve the tessl finding. Investigate the staging SKILL.md frontmatter for non-angle-bracket content that tessl is still rejecting, and patch §2a accordingly. Do not edit the description manually." Do not proceed to §6b user prompt on an unrecovered failure.
|
|
19
|
-
|
|
20
|
-
A `description_score` (LLM judge %) below 100 **without** an accompanying `description_field` finding is **not** a recovery trigger and **not** a halt condition: record `description_judge_score: {n}% (deterministic description_field validator PASSED)` as a warning in the evidence report and continue to suggestion handling. The recover-then-halt path is reserved for the deterministic validator.
|
|
21
|
-
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
## Suggestion Dismissal Rules
|
|
25
|
-
|
|
26
|
-
Each rule below describes a tessl suggestion that Skill Forge expects and dismisses automatically. For each `judge_suggestion` in tessl output, check it against these rules in order. If any rule matches, record the dismissal in the evidence report (`rule_id`, `rationale`) and do not apply the suggestion. If no rule matches, the suggestion is novel and must surface to the user in §6b.
|
|
27
|
-
|
|
28
|
-
### Rule: `remove-manual-markers`
|
|
29
|
-
|
|
30
|
-
- **Scorer:** any
|
|
31
|
-
- **Match criteria (any of):**
|
|
32
|
-
- Suggestion text contains `[MANUAL]` AND one of: `remove`, `delete`, `strip`, `clean up`
|
|
33
|
-
- Suggestion text contains `manual marker` AND one of: `remove`, `delete`, `unnecessary`
|
|
34
|
-
- **Rationale:** `<!-- [MANUAL] -->` markers delineate author-added content that `skf-update-skill` preserves during merge operations. Removing them would cause update-skill to overwrite author edits on the next run. The markers are a load-bearing contract between create-skill, test-skill, and update-skill.
|
|
35
|
-
- **Action:** dismiss.
|
|
36
|
-
|
|
37
|
-
### Rule: `move-full-api-reference`
|
|
38
|
-
|
|
39
|
-
- **Scorer:** any
|
|
40
|
-
- **Match criteria (all of):**
|
|
41
|
-
- Suggestion text mentions `Full API Reference` OR a `## Full ...` section heading
|
|
42
|
-
- Suggestion text contains one of: `move`, `relocate`, `extract`, `split out`, `separate file`, `external file`
|
|
43
|
-
- **Rationale:** The two-tier design (Tier 1 inline + Tier 2 inline) keeps Tier 2 sections inline by default. `skill-check split-body` relocates Tier 2 to `references/` only when the body exceeds size limits — see step 6 §4. Preemptive relocation destroys the standalone SKILL.md that the cited 100% task accuracy (vs. 79% for on-demand retrieval) depends on.
|
|
44
|
-
- **Action:** dismiss.
|
|
45
|
-
|
|
46
|
-
### Rule: `consolidate-duplicate-parameters`
|
|
47
|
-
|
|
48
|
-
- **Scorer:** `conciseness` or any
|
|
49
|
-
- **Match criteria (any of):**
|
|
50
|
-
- Suggestion mentions `duplicate parameter`, `redundant parameter`, `consolidate parameter`
|
|
51
|
-
- Suggestion mentions both `Key API` / `Key API Summary` AND `Full API Reference` and suggests merging them
|
|
52
|
-
- **Rationale:** Tier 1 Key API Summary intentionally lists only key parameters for standalone discoverability. Tier 2 Full API Reference provides complete parameter tables, types, defaults, and edge cases. This is progressive disclosure, not duplication. Consolidating would force agents to scroll to Tier 2 for the most common function calls, defeating Tier 1's purpose and breaking the split-body Tier 1 preservation contract in step 6 §4.
|
|
53
|
-
- **Action:** dismiss.
|
|
54
|
-
|
|
55
|
-
### Rule: `conciseness-redundancy-between-tiers`
|
|
56
|
-
|
|
57
|
-
- **Scorer:** `conciseness`
|
|
58
|
-
- **Match criteria (all of):**
|
|
59
|
-
- Scorer is `conciseness`
|
|
60
|
-
- Suggestion or score rationale references redundancy between Tier 1 and Tier 2 sections (typically `Key API` ↔ `Full API` or `Quick Start` ↔ `Full Reference`)
|
|
61
|
-
- **Expected score:** 2/3 is normal. 3/3 is only achievable by collapsing the two-tier design.
|
|
62
|
-
- **Rationale:** Progressive disclosure is the intentional SKF design. The conciseness scorer has no concept of Tier 1 / Tier 2 and flags the structure as redundancy. Collapsing the two tiers would eliminate standalone discoverability and break split-body behavior.
|
|
63
|
-
- **Action:** dismiss. Do not attempt to raise the score above 2/3.
|
|
64
|
-
|
|
65
|
-
### Rule: `provenance-citations-required`
|
|
66
|
-
|
|
67
|
-
- **Scorer:** `conciseness`, `actionability`, or any
|
|
68
|
-
- **Match criteria (any of):**
|
|
69
|
-
- Suggestion text references `[SRC:`, `[AST:`, `[QMD:`, or `[EXT:` annotations AND one of: `remove`, `strip`, `omit`, `drop`
|
|
70
|
-
- Suggestion mentions `provenance annotations`, `source citations`, or `source markers` AND one of: `remove`, `unnecessary`, `token bloat`, `token cost`
|
|
71
|
-
- **Expected score:** `conciseness` 1/3 is normal while inline provenance annotations are present. Raising it would require stripping the annotations.
|
|
72
|
-
- **Rationale:** SKF's zero-hallucination policy requires every claim in SKILL.md to carry a provenance citation — see the "Signature fidelity" rule in `assets/compile-assembly-rules.md` and the "Provenance Citation Format" table in `assets/skill-sections.md`. Removing them would break the provenance audit trail and the trust contract that lets `skf-update-skill` detect source drift and `skf-audit-skill` verify claims against source.
|
|
73
|
-
- **Action:** dismiss.
|
|
74
|
-
|
|
75
|
-
### Rule: `description-xml-tags-guarded-upstream`
|
|
76
|
-
|
|
77
|
-
- **Scorer:** `description_field` (deterministic validator)
|
|
78
|
-
- **Match criteria (any of):**
|
|
79
|
-
- Finding rule ID is `description_field` AND message mentions `XML tag`, `must not contain`, or angle-bracket-related text
|
|
80
|
-
- **Expected occurrence:** zero. step 5 §2a unconditionally replaces `<` with `{` and `>` with `}` in the frontmatter description before SKILL.md is written.
|
|
81
|
-
- **Action:** **Attempt recovery, then halt if recovery fails.** This is not a dismissal — the finding represents a real sanitizer bypass that step 6 must resolve before proceeding.
|
|
82
|
-
1. **Re-apply §2a in place.** Read the current `description` from the on-disk staging SKILL.md frontmatter, replace every `<` with `{` and every `>` with `}`, and write the result back to the frontmatter. Re-sync the in-context copy to match. Count the substitutions; if zero, the description is already clean and the tessl finding points at something other than angle brackets — skip to the halt branch below.
|
|
83
|
-
2. **Re-run tessl once.** Execute `npx -y tessl skill review <staging-skill-dir>` a second time and re-parse the JSON output.
|
|
84
|
-
3. **On success** (the `description_field` finding is absent from the re-run): log `description-recovery: applied ({count} substitutions)` in the evidence report under "Dismissed tessl suggestions", then continue §6 with the recovered review result (proceed to normal suggestion handling against the rules below). The rerun's `judge_suggestions[]` replaces the original. A residual judge `description_score < 100` on the re-run is a warning, not a failure — recovery success is keyed on the deterministic finding clearing, not on the judge percentage reaching 100.
|
|
85
|
-
4. **On failure** (the `description_field` finding persists after re-sanitization): halt with: "Description sanitization recovery failed — step 5 §2a's `<`/`>` → `{`/`}` replacement did not resolve the tessl finding. Investigate the staging SKILL.md frontmatter for non-angle-bracket content that tessl is still rejecting, and patch §2a accordingly. Do not edit the description manually."
|
|
86
|
-
|
|
87
|
-
The recovery path makes the skill shippable when a downstream tool (`skill-check --fix`, `split-body`, or a future validator) re-introduces angle brackets into the description after §2a has run. The Description Guard Protocol in step 6 §0 is the first line of defense against such rewrites; this rule is the second line, active when the guard also missed.
|
|
88
|
-
|
|
89
|
-
---
|
|
90
|
-
|
|
91
|
-
## How Step-06 §6 Uses This File
|
|
92
|
-
|
|
93
|
-
1. Load this file completely at the start of §6.
|
|
94
|
-
2. Run `npx -y tessl skill review <staging-skill-dir>` and parse JSON output.
|
|
95
|
-
3. Check score thresholds. For a deterministic `description_field` finding (angle-bracket / XML-tag rejection): follow the recovery-then-halt path described in the threshold table above and the `description-xml-tags-guarded-upstream` rule below — re-apply §2a in place, re-run tessl once, and continue on recovery success (finding cleared) or halt on recovery failure. A judge `description_score` below 100 while the `description_field` validator passes is a warning, not a halt. For other warns: continue, log warnings to evidence report.
|
|
96
|
-
4. For each `judge_suggestions[]` entry in the output:
|
|
97
|
-
a. Iterate the rules above in order.
|
|
98
|
-
b. If a rule's match criteria are satisfied, record `{rule_id, rationale, suggestion_text}` in the evidence report under "Dismissed tessl suggestions" and move to the next suggestion.
|
|
99
|
-
c. If no rule matches, add the suggestion to the "Novel tessl suggestions" list that §6b surfaces to the user.
|
|
100
|
-
5. Proceed to §6b if any novel suggestions exist, or auto-proceed if all suggestions were dismissed.
|
|
101
|
-
|
|
102
|
-
---
|
|
103
|
-
|
|
104
|
-
## Evolving This List
|
|
105
|
-
|
|
106
|
-
When tessl changes or an SKF design decision shifts, add a new rule section above (`Rule:` / `Scorer:` / `Match criteria` / `Rationale` / `Action`), link each rationale to the concrete SKF design principle it protects (two-tier design, MANUAL markers, sanitization, split-body preservation — a rationale without such a link is a smell), and keep score thresholds at or above current production floors — never lower them to suppress real regressions.
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
nextStepFile: 'sub/ccc-discover.md'
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
<!-- Config: communicate in {communication_language}. -->
|
|
6
|
-
|
|
7
|
-
# Step 2: Ecosystem Check
|
|
8
|
-
|
|
9
|
-
## STEP GOAL:
|
|
10
|
-
|
|
11
|
-
To search the agentskills.io ecosystem for an existing official skill matching the brief, advise the user if one is found, and allow them to decide whether to proceed with compilation or install the existing skill.
|
|
12
|
-
|
|
13
|
-
## Rules
|
|
14
|
-
|
|
15
|
-
- Focus only on ecosystem search and presenting findings — do not begin extraction
|
|
16
|
-
- Do not halt the workflow if the ecosystem check fails or times out (5-second timeout)
|
|
17
|
-
- If a match is found, present it factually — let the user decide
|
|
18
|
-
|
|
19
|
-
## MANDATORY SEQUENCE
|
|
20
|
-
|
|
21
|
-
### 1. Check Ecosystem for Existing Skill
|
|
22
|
-
|
|
23
|
-
**Note:** Ecosystem lookup requires the agentskills.io registry API, which is not yet available. The `skill-check` CLI validates local skills but does not query a remote registry.
|
|
24
|
-
|
|
25
|
-
**If agentskills.io registry API is available:**
|
|
26
|
-
|
|
27
|
-
Query the ecosystem using the skill name from the brief:
|
|
28
|
-
- Call the registry API with brief.name — check if an official skill already exists
|
|
29
|
-
- Enforce 5-second timeout — if the query does not return within 5 seconds, treat as no match. Rationale: ecosystem check is an opportunistic advisory; a slow or degraded registry must not stall the compilation pipeline, and 5s is well beyond any healthy registry's p99 latency.
|
|
30
|
-
- Cache results for 24 hours (if re-running same skill). Rationale: the agentskills.io registry publishes new official skills in daily batches; a 24-hour TTL balances freshness against redundant network calls during iterative brief refinement.
|
|
31
|
-
|
|
32
|
-
**If registry API is not available (current default):**
|
|
33
|
-
|
|
34
|
-
Skip completely and silently. Do not output any message about API unavailability or the ecosystem check being skipped. Emit zero text to the console. Proceed exactly as if no match was found.
|
|
35
|
-
|
|
36
|
-
### 2. Evaluate Results
|
|
37
|
-
|
|
38
|
-
**If match found (official skill exists):**
|
|
39
|
-
|
|
40
|
-
Present the finding to the user:
|
|
41
|
-
|
|
42
|
-
"**Ecosystem match found.**
|
|
43
|
-
|
|
44
|
-
**Existing skill:** {matched_skill_name} v{matched_version}
|
|
45
|
-
**Source:** {matched_source}
|
|
46
|
-
**Authority:** {official/community}
|
|
47
|
-
**Compatibility:** {compatibility_notes}
|
|
48
|
-
|
|
49
|
-
An existing skill already covers this source. You can:
|
|
50
|
-
- **[P] Proceed** — compile your own version anyway (useful for customization or different scope)
|
|
51
|
-
- **[I] Install** — install the existing skill instead of compiling
|
|
52
|
-
- **[A] Abort** — cancel this compilation"
|
|
53
|
-
|
|
54
|
-
**If no match found:**
|
|
55
|
-
|
|
56
|
-
Auto-proceed silently to next step. Do not display any message about the ecosystem check — absence of a match is the expected case.
|
|
57
|
-
|
|
58
|
-
**If timeout or error:**
|
|
59
|
-
|
|
60
|
-
Auto-proceed silently. Log a note in context: "Ecosystem check skipped (timeout/error) — proceeding with compilation."
|
|
61
|
-
|
|
62
|
-
### 3. Gate — Ecosystem Match (conditional)
|
|
63
|
-
|
|
64
|
-
This gate fires only when §2 found a match; on no match, timeout, or unavailable tool the step already auto-proceeded to `{nextStepFile}` with no menu.
|
|
65
|
-
|
|
66
|
-
**GATE [default: P]** — under `{headless_mode}` with a match, auto-proceed as [P], log "headless: ecosystem match found, auto-proceeding", and append `{step: "ecosystem-check", gate: "ecosystem-match", decision: "P", rationale: "headless mode — match found, auto-proceed with user's own compilation", timestamp: {ISO}}` to `headless_decisions[]` and, the moment it lands, append the same object as a JSON line to the durable audit sink `{sidecar_path}/auto-decisions.jsonl` (the on-landing append established at step 1 §3) — the sink feeds the evidence-report `## Auto-Decisions` table at step 5 §7 and step 6 §8.
|
|
67
|
-
|
|
68
|
-
Interactively, halt and wait for the user's choice on the §2 menu:
|
|
69
|
-
|
|
70
|
-
- **P** — proceed despite the existing skill; load `{nextStepFile}`, read it fully, then execute it.
|
|
71
|
-
- **I** — display "Install the existing skill using: `[SF] Setup Forge → install {matched_skill_name}`", then halt (no extraction).
|
|
72
|
-
- **A** — display "Compilation aborted. Return to Ferris menu to select another action.", then halt.
|
|
73
|
-
- Any other question — answer it, then redisplay the menu.
|
|
74
|
-
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
# Headless Result Envelope
|
|
2
|
-
|
|
3
|
-
The single-line JSON contract every headless run of skf-drop-skill emits. It stands alone: the stages that emit it load this file directly, so an error path never depends on any other file staying in context under compaction.
|
|
4
|
-
|
|
5
|
-
When `{headless_mode}` is true, step 3 emits this envelope on **stdout** before chaining to step 4; every HARD HALT emits the same shape on **stderr** with `status: "error"`:
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
SKF_DROP_SKILL_RESULT_JSON: {"status":"success|error|dry-run","skill":"…|null","drop_mode":"…|null","versions_affected":[],"files_deleted":[],"manifest_updated":false,"exit_code":0,"halt_reason":null}
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
Field rules:
|
|
12
|
-
|
|
13
|
-
- `status` — `"success"` on the terminal happy path, `"dry-run"` when `--dry-run` was set and the workflow exited at the confirmation gate before any mutation, `"error"` on any HALT.
|
|
14
|
-
- `halt_reason` — `null` on success/dry-run; otherwise one of `"input-missing"`, `"input-invalid"`, `"manifest-corrupt"`, `"nothing-to-drop"`, `"active-version-guard-refused"`, `"headless-purge-forbidden"`, `"manifest-write-failed"`, `"context-rebuild-failed"`, `"delete-failed"`, `"write-failed"`, `"user-cancelled"`.
|
|
15
|
-
- `exit_code` — the stable numeric code the emitting HALT specifies (`0` on success/dry-run).
|
|
16
|
-
- `skill` / `drop_mode` / `versions_affected` / `files_deleted` / `manifest_updated` — the discriminating values the emit site supplies; any key not yet resolved at that point takes the default shown in the template (`null`, `[]`, or `false`).
|
|
17
|
-
|
|
18
|
-
Each emit site supplies its own `exit_code`, `halt_reason`, and whichever discriminating fields are known at that point; all other keys default as shown.
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: static-reference
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Merge Conflict Rules
|
|
6
|
-
|
|
7
|
-
> Change-category actions and the merge priority order (deleted → moved → renamed → modified → new, plus the gap-driven priorities) are specified authoritatively in `merge.md` §3. This reference carries only the one thing §3 does not: the conflict-resolution strategy table below.
|
|
8
|
-
|
|
9
|
-
## Conflict Resolution Strategies
|
|
10
|
-
|
|
11
|
-
| Strategy | When | Action |
|
|
12
|
-
|--------------|-------------------------------------|-------------------------------------------|
|
|
13
|
-
| Auto-resolve | No [MANUAL] conflicts, clean merge | Proceed without user input |
|
|
14
|
-
| User-resolve | [MANUAL] conflicts detected | Halt, present conflicts, require decision |
|
|
15
|
-
| Abort | Critical structural incompatibility | Stop workflow, recommend full re-creation |
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: static-reference
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Remote Source Resolution (Forge/Deep Tier)
|
|
6
|
-
|
|
7
|
-
If `source_root` is a local path: proceed with the tier-appropriate strategy as normal.
|
|
8
|
-
|
|
9
|
-
If `source_root` (from metadata.json) is a remote URL (GitHub URL or owner/repo format) AND tier is Forge or Deep:
|
|
10
|
-
|
|
11
|
-
1. **Check `git` availability:** Verify `git` is functional (`git --version`). If `git` is not available, skip to the fallback warning below.
|
|
12
|
-
|
|
13
|
-
2. **Resolve source ref:** Read `source_ref` from the existing `metadata.json`. If the user provided a new `target_version`, resolve its tag first (using the Tag Resolution algorithm in `create-skill/references/source-resolution-protocols.md`).
|
|
14
|
-
|
|
15
|
-
**Note — implicit tag resolution is NOT re-run on update:** `create-skill`'s Implicit Tag Resolution path (which treats `brief.version` as an implicit `target_version` for remote sources) runs only at create time. On update, `skf-update-skill` faithfully re-uses the `source_ref` that was stored in `metadata.json` by the original create — even if that ref is `HEAD` and the brief now has a `version` that would resolve to a tag. This preserves the invariant that an update reflects source drift on the same ref the skill was originally built against, not a re-pinning to a different commit. If the intent is to re-pin an older HEAD-based skill to a tag derived from `brief.version`, re-run `skf-create-skill` (which applies implicit resolution) rather than `skf-update-skill`. Explicit re-pinning via a new `target_version` on update remains supported and takes priority over the stored `source_ref`.
|
|
16
|
-
|
|
17
|
-
3. **Workspace check:** Compute the workspace path using the same algorithm as `create-skill/references/source-resolution-protocols.md` (parse URL → `{workspace_root}/repos/{host}/{owner}/{repo}/`).
|
|
18
|
-
|
|
19
|
-
**If workspace repo exists (`{workspace_repo_path}/.git/` present):**
|
|
20
|
-
|
|
21
|
-
Fetch and checkout the requested ref. For update-skill, `changed_files_from_manifest` scoping happens at extraction time via file-level filtering — the workspace has a full checkout.
|
|
22
|
-
|
|
23
|
-
```
|
|
24
|
-
git -C "{workspace_repo_path}" fetch origin {source_ref}
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
Check if checkout is needed — skip if the requested ref is already checked out:
|
|
28
|
-
|
|
29
|
-
```
|
|
30
|
-
current_head = git -C "{workspace_repo_path}" rev-parse HEAD
|
|
31
|
-
fetched_head = git -C "{workspace_repo_path}" rev-parse FETCH_HEAD
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
If `current_head != fetched_head`:
|
|
35
|
-
```
|
|
36
|
-
git -C "{workspace_repo_path}" -c advice.detachedHead=false checkout FETCH_HEAD
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
Set `remote_clone_path = {workspace_repo_path}`, `remote_clone_type = "workspace"`.
|
|
40
|
-
|
|
41
|
-
**If workspace repo does NOT exist:**
|
|
42
|
-
|
|
43
|
-
Clone into workspace. Create the parent directory first:
|
|
44
|
-
|
|
45
|
-
```
|
|
46
|
-
mkdir -p "{workspace_root}/repos/{host}/{owner}/"
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
Clone with the appropriate branch flag — `--branch` is only valid for real branch/tag names, not for `HEAD`:
|
|
50
|
-
|
|
51
|
-
```
|
|
52
|
-
# If source_ref is a real branch or tag (not HEAD/null/"local"):
|
|
53
|
-
git clone --depth 1 --branch {source_ref} --single-branch "{source_repo}" "{workspace_repo_path}"
|
|
54
|
-
|
|
55
|
-
# If source_ref is HEAD or not set (default branch):
|
|
56
|
-
git clone --depth 1 --single-branch "{source_repo}" "{workspace_repo_path}"
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
Set `remote_clone_path = {workspace_repo_path}`, `remote_clone_type = "workspace"`.
|
|
60
|
-
|
|
61
|
-
**On any workspace failure:** Fall back to ephemeral clone:
|
|
62
|
-
```
|
|
63
|
-
temp_path = {system_temp}/skf-ephemeral-{skill-name}-{timestamp}/
|
|
64
|
-
|
|
65
|
-
# If source_ref is a real branch or tag (not HEAD/null/"local"):
|
|
66
|
-
git clone --depth 1 --branch {source_ref} --single-branch --filter=blob:none "{source_root}" "{temp_path}"
|
|
67
|
-
|
|
68
|
-
# If source_ref is HEAD or not set (default branch):
|
|
69
|
-
git clone --depth 1 --single-branch --filter=blob:none "{source_root}" "{temp_path}"
|
|
70
|
-
```
|
|
71
|
-
Set `remote_clone_path = {temp_path}`, `remote_clone_type = "ephemeral"`.
|
|
72
|
-
|
|
73
|
-
4. **If clone/fetch succeeds:** Set `source_root = {remote_clone_path}` — this updates the working source path for all subsequent operations. Apply `changed_files_from_manifest` as file-level filters at extraction time. Proceed with the **Forge tier** extraction strategy below.
|
|
74
|
-
|
|
75
|
-
5. **If all cloning fails (workspace AND ephemeral):**
|
|
76
|
-
|
|
77
|
-
Warning message: "Clone of `{source_root}` failed: {error}. Degrading to source reading (T1-low) for this run. For T1 (AST-verified) confidence, clone the repository locally and re-run [CS] Create Skill with the local path, then re-run this update."
|
|
78
|
-
|
|
79
|
-
Override the extraction strategy to Quick tier for this run. Note the degradation reason in context for the evidence report.
|
|
80
|
-
|
|
81
|
-
## Remote Clone Cleanup
|
|
82
|
-
|
|
83
|
-
After extraction is complete for all files in scope (whether successful or partially failed), before presenting the extraction summary:
|
|
84
|
-
|
|
85
|
-
- **If `remote_clone_type == "ephemeral"`:** Reset the working directory first (`cd "{project-root}"` using the absolute path captured at workflow start), then delete the `{temp_path}` directory (`rm -rf "{temp_path}"`). Log: "Ephemeral source clone cleaned up." This ensures cleanup runs even if some extractions failed.
|
|
86
|
-
- **If `remote_clone_type == "workspace"`:** No cleanup. The workspace checkout persists for future forges and updates.
|
|
87
|
-
|
|
88
|
-
## Version Reconciliation
|
|
89
|
-
|
|
90
|
-
After the source path is accessible, check whether the source version has changed since the original skill was created. Look for the version file matching the detected language (e.g., `pyproject.toml`, `package.json`, `Cargo.toml`). If the source version differs from the current `metadata.json` version, record `source_version_detected` in context for step 6 to use when updating `metadata.json`. No warning needed here — step 6 handles the version update.
|
|
91
|
-
|
|
92
|
-
## AST Tool Unavailability (Local Source)
|
|
93
|
-
|
|
94
|
-
If AST tool is unavailable at Forge/Deep tier with local source:
|
|
95
|
-
|
|
96
|
-
Warning message: "AST tools are unavailable — extraction will use source reading (T1-low). Run [SF] Setup Forge to detect and configure AST tools for T1 confidence."
|
|
97
|
-
|
|
98
|
-
Degrade to Quick tier extraction. Note the degradation reason in context for the evidence report.
|