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
|
@@ -2,16 +2,11 @@
|
|
|
2
2
|
nextStepFile: 'merge.md'
|
|
3
3
|
extractionPatternsData: 'skf-create-skill/references/extraction-patterns.md'
|
|
4
4
|
extractionPatternsTracingData: 'skf-create-skill/references/extraction-patterns-tracing.md'
|
|
5
|
-
remoteSourceResolutionData: 'references/remote-source-resolution.md'
|
|
6
5
|
tierDegradationRulesData: 'skf-create-skill/references/tier-degradation-rules.md'
|
|
7
|
-
#
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
# lose the four-state dispatch (ok / skipped / mismatch / overridden).
|
|
12
|
-
checkWorkspaceDriftProbeOrder:
|
|
13
|
-
- '{project-root}/_bmad/skf/shared/scripts/skf-check-workspace-drift.py'
|
|
14
|
-
- '{project-root}/src/shared/scripts/skf-check-workspace-drift.py'
|
|
6
|
+
# `{buildChangeManifestHelper}`: §4's `records`. HALT if neither exists.
|
|
7
|
+
buildChangeManifestProbeOrder:
|
|
8
|
+
- '{project-root}/_bmad/skf/shared/scripts/skf-build-change-manifest.py'
|
|
9
|
+
- '{project-root}/src/shared/scripts/skf-build-change-manifest.py'
|
|
15
10
|
---
|
|
16
11
|
|
|
17
12
|
<!-- Config: communicate in {communication_language}. -->
|
|
@@ -20,248 +15,85 @@ checkWorkspaceDriftProbeOrder:
|
|
|
20
15
|
|
|
21
16
|
## STEP GOAL:
|
|
22
17
|
|
|
23
|
-
Perform tier-aware extraction on only the changed files identified in step
|
|
18
|
+
Perform tier-aware extraction on only the changed files identified in step 2, producing fresh export data with confidence tier labels (T1/T1-low/T2) that will be merged into the existing skill in step 4.
|
|
24
19
|
|
|
25
20
|
## Rules
|
|
26
21
|
|
|
27
22
|
- Focus only on extracting changed exports — do not merge or modify existing skill
|
|
28
|
-
- Only extract files in the change manifest
|
|
29
|
-
- For each changed file, launch a subprocess
|
|
23
|
+
- Only extract files in the change manifest: do not touch unchanged files
|
|
24
|
+
- For each changed file, launch a subprocess (Pattern 2) that reads its exports at the lines step 2 recorded (§1b); if unavailable, extract sequentially
|
|
30
25
|
|
|
31
26
|
## Steps
|
|
32
27
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
**If `update_mode == "gap-driven"` (set in step 1 via `--from-test-report`, confirmed in step 2 section 0):**
|
|
36
|
-
|
|
37
|
-
Source code has not drifted — the gap-derived manifest from step 2 contains export-level findings translated from the test report, not file-level changes. Perform citation spot-checks instead of full re-extraction to verify each gap-affected export is still at its recorded location.
|
|
38
|
-
|
|
39
|
-
**0.a Pre-flight: verify workspace HEAD matches pinned commit.** Gap-driven spot-checks read source at recorded `source_line` positions and must see the exact bytes the skill was pinned against. A drifted workspace silently verifies against the wrong tree — moved/renamed symbols appear "verified" because the recorded line now points at different code. Before reading any source, run the guard via `{checkWorkspaceDriftHelper}`:
|
|
28
|
+
**Halt procedure.** Every HALT in this step names its payload (`status`, `phase`, `path` when it has one, and `reason`), displays its message, and then runs, from `{project-root}`, the halt helper SKILL.md On Activation resolved. This step writes nothing outside `{run_dir}`, so there is nothing to undo, `--dry-run` included.
|
|
40
29
|
|
|
41
30
|
```bash
|
|
42
|
-
uv run {
|
|
43
|
-
--
|
|
44
|
-
[--
|
|
45
|
-
[--
|
|
31
|
+
uv run {runStateHelper} halt --run-dir "{run_dir}" \
|
|
32
|
+
[--tree "{source_tree}"] \
|
|
33
|
+
[--lock "{forge_data_folder}/{skill_name}/.skf-update.lock" --owner "{lock_owner}"] \
|
|
34
|
+
[--emit] <<'SKF_JSON'
|
|
35
|
+
{"status": "<status>", "phase": "<phase>", "path": "<path; leave the key out when the halt names none>", "reason": "<reason>", "skill_name": "{skill_name}", "version": "<the metadata.json version>", "previous_version": "<the same>", "update_mode": "<normal or degraded>"}
|
|
36
|
+
SKF_JSON
|
|
46
37
|
```
|
|
47
38
|
|
|
48
|
-
Pass `--
|
|
49
|
-
|
|
50
|
-
The helper emits a result envelope:
|
|
51
|
-
|
|
52
|
-
```json
|
|
53
|
-
{
|
|
54
|
-
"status": "ok" | "skipped" | "mismatch" | "overridden",
|
|
55
|
-
"skip_reason": "no-pinned-commit" | "not-a-git-tree" | null,
|
|
56
|
-
"head_sha": "...", "head_short_sha": "...", "match_kind": "full" | "short-prefix" | null,
|
|
57
|
-
"log_message": "workspace_drift_check: ...",
|
|
58
|
-
"halt_message": "<multi-line user-facing message>" | null
|
|
59
|
-
}
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
**Dispatch on `status`:**
|
|
63
|
-
|
|
64
|
-
- **`ok` or `skipped`** (helper exit 0): log `log_message` and continue to bullet 1.
|
|
65
|
-
- **`overridden`** (helper exit 0): log `log_message`, surface a visible warning in the final report ("**Workspace drift accepted via --allow-workspace-drift** — spot-checks read HEAD {head_short_sha}, not pinned {pinned_commit}"), and continue to bullet 1. The override does not automatically re-pin `metadata.source_commit`; re-pinning is explicit user work (run the normal-mode update-skill flow against the same HEAD, or re-create the skill).
|
|
66
|
-
- **`mismatch`** (helper exit 2): HALT immediately with status `halted-for-workspace-drift`. Display the helper's `halt_message` verbatim — it already substitutes `{pinned_commit}`, `{source_ref or "unset"}`, `{source_root}`, `{head_sha}`, and the suggested `git checkout` command. Do not proceed to bullet 1. Step-04 merge has not run; no partial writes. In `{headless_mode}`, emit the halt envelope per SKILL.md §Headless (`error: {phase: "re-extract:workspace-drift", path: "{source_root}", reason: "..."}`).
|
|
67
|
-
|
|
68
|
-
1. Use the provenance map already loaded in step 1 (at `{forge_version}/provenance-map.json`) — do not re-read
|
|
69
|
-
2. **Partition by change category, then iterate the export-bearing entries.** Entries that do not name an export skip the per-export verification below — they have no symbol to resolve against source:
|
|
70
|
-
- **`STRUCTURAL_FIX`** (detect-changes §0 rule R2): forward verbatim to the merge step (its `remediation` text describes a generated-markdown edit). No spot-check, no provenance lookup, no `entries[]` change.
|
|
71
|
-
- **`metadata update`** (rule R4): forward the metadata-patch payload to the merge step. No spot-check, no provenance lookup.
|
|
72
|
-
|
|
73
|
-
Carry both through workflow context to merge.md unchanged. Then, for each export-bearing entry (`NEW_EXPORT`, `MODIFIED_EXPORT`, `DELETED_EXPORT`):
|
|
74
|
-
- **If the entry is `DELETED_EXPORT` (rescope, rule R1):** do not resolve against source — the export is being removed from the public surface. Record `verification: rescoped` and flag for merge Priority 1 (removal). Confirm the brief carries the matching `scope.amendments[]` (`action: "excluded"`) + `scope.exclude` entry that step 2 R1 wrote; if absent, HALT — a rescope without a brief scope amendment is denominator deflation and must not be written.
|
|
75
|
-
- Look up the export by `name` in `provenance_map.exports` — read `source_file` and `source_line`
|
|
76
|
-
- **If export not found in provenance map:**
|
|
77
|
-
- **If the manifest entry has a `source_citation` (propagated from the test report by step 2 §0 bullet 4):** read the file at that citation's `file:line ± 5` lines and verify the symbol name still appears within that window. Record a full `verified` / `moved` / `missing` entry using the citation as the starting location — same spot-check logic as the "export found" branch below, keyed on the manifest-supplied citation instead of the provenance map. The export is still flagged `NEW_EXPORT` for the merge step; this branch only upgrades the provenance entry from `unknown` to a live spot-check result so step 6 writes `source_file` / `source_line` instead of `null`.
|
|
78
|
-
- **If the entry is a provenance-completeness gap (rule R3 — documented in SKILL.md/`references/` but missing from the provenance-map) AND `source_root` is pinned and readable:** route this entry to §0a (Targeted Re-Extraction Branch) **regardless of severity**. These exports are documented-and-known; `unknown` is never the correct outcome for them. §0a resolves them against pinned source and records a full `re-extracted` provenance entry. This route takes precedence over the severity-gated branches below.
|
|
79
|
-
- **If the manifest entry has no `source_citation` but has a non-empty `remediation_paths[]` AND `severity` is `Critical` or `High`:** route this entry to §0a (Targeted Re-Extraction Branch). §0a scans the remediation paths with the tier-appropriate extractor and, on success, records a full verification record with `verification: re-extracted`, a live `provenance_citation`, and full signature/params/return-type fields for the merge step to consume as a NEW_EXPORT. On failure, §0a halts the workflow — Critical/High gaps are not allowed to degrade to `unknown`. See §0a for the procedure, the consolidated halt protocol, and the output record shape.
|
|
80
|
-
- **If the manifest entry has no `source_citation` AND (`remediation_paths[]` is empty OR `severity` is `Medium`, `Low`, or `Info`) AND it is not a provenance-completeness gap:** record as new (`provenance_citation: unknown`) — no spot-check possible; flag for merge step to handle as `NEW_EXPORT`. Step-06 §3 only accepts null `source_file` / `source_line` for these lower-severity unknowns; a Critical/High unknown reaching step 6 indicates §0a was skipped or bypassed and is a workflow bug.
|
|
81
|
-
- **If export found:** read the source file at `source_line ± 5` lines and verify the symbol name still appears within that window
|
|
82
|
-
- Record verification outcome: `verified` (symbol at recorded line), `moved` (symbol found elsewhere in same file — record new line), `missing` (symbol not found in file), `re-extracted` (resolved via §0a from `remediation_paths[]` or rule R3), `rescoped` (DELETED_EXPORT — flagged for removal), or `unknown` (no usable provenance data)
|
|
83
|
-
- **Public-reachability gate (`NEW_EXPORT` only):** before an entry is flagged `NEW_EXPORT` for the merge step, confirm the symbol is reachable as **public API** — not merely that a `pub` / `export` / top-level definition exists at the citation. The spot-check already read `source_file` at `source_line ± 5`; extend that read to resolve the symbol's module path and confirm at least one of: (a) it is re-exported from the package entry-point barrel (`lib.rs` `pub use`, `index.ts` / `index.js` export, `__init__.py` import or `__all__`), or (b) every ancestor module on the path from that barrel is public (Rust `pub mod`, an exported TS namespace, a non-underscore Python package). A `pub(crate)` / `pub(super)` item, or one under a private module (e.g. `mod authority;` declared without `pub`), is **not** reachable. **On failure:** do not document it as public — drop it from the export-bearing set so it is never written to the documented `exports[]` array or SKILL.md, and re-queue it as a `metadata update` (rule R4) recording `reclassified: internal-unreachable` for the evidence report. Do **not** hand-set any `stats` count: write.md §2's automatic recount derives `exports_internal` / `exports_total` from the merged surface and owns those fields. This honors the workflow rule that documented API must be importable by users — a `pub`-but-internal symbol would otherwise inflate the documented public surface with a type users cannot import.
|
|
84
|
-
3. Build a minimal extraction results block matching section 4's shape, with `mode: gap-driven` and per-export verification records:
|
|
85
|
-
|
|
86
|
-
```
|
|
87
|
-
Extraction Results:
|
|
88
|
-
mode: gap-driven
|
|
89
|
-
files_extracted: {count} # non-zero only when §0a scanned remediation_paths[]
|
|
90
|
-
exports_extracted: {gap_count}
|
|
91
|
-
confidence_breakdown:
|
|
92
|
-
T1: {verified_count + moved_count + re_extracted_t1_count}
|
|
93
|
-
T1-low: {re_extracted_t1_low_count}
|
|
94
|
-
T2: 0
|
|
95
|
-
|
|
96
|
-
Per-export verification:
|
|
97
|
-
{export_name}:
|
|
98
|
-
provenance_citation: {source_file}:{source_line}
|
|
99
|
-
verification: verified|moved|missing|unknown|re-extracted|rescoped
|
|
100
|
-
new_location: {source_file}:{new_line} # set when moved OR re-extracted
|
|
101
|
-
resolution_source: remediation-paths # set only when verification == re-extracted
|
|
102
|
-
gap_category: NEW_EXPORT|MODIFIED_EXPORT|DELETED_EXPORT|metadata_update
|
|
103
|
-
|
|
104
|
-
Per-file extractions: # populated only when §0a produced re-extracted records
|
|
105
|
-
{file_path}:
|
|
106
|
-
exports:
|
|
107
|
-
- name: {export_name}
|
|
108
|
-
type: function|class|type|constant
|
|
109
|
-
signature: {full signature}
|
|
110
|
-
location: {file}:{start_line}-{end_line}
|
|
111
|
-
confidence: T1|T1-low
|
|
112
|
-
params: [{name, type}]
|
|
113
|
-
return_type: {type}
|
|
114
|
-
docstring: {summary}
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
4. Set `no_reextraction: true` in workflow context — step 6 will use this flag to skip stale `source_file`/`source_line`/`confidence` field updates for `verified` exports. `moved` exports get updated citations; `re-extracted` exports get full fresh provenance from §0a's extraction records (see step 6 §3). The flag is a global gap-driven marker, not a per-entry one — step 6 dispatches on each verification outcome independently.
|
|
118
|
-
5. **Skip all remaining sections of step 3** — sections 1–5 are source-drift extraction paths that do not apply. Display the summary below and load `{nextStepFile}` to proceed directly to the merge step.
|
|
39
|
+
Pass `--tree` when init.md §6b bound `{source_tree}`, `--lock` and `--owner` when init.md §1b bound `{lock_owner}` (the read-only modes take no lock), and `--emit` in `{headless_mode}`. It removes the private source tree, releases the run lock (never one another run holds) and, with `--emit`, prints the halt's `SKF_UPDATE_RESULT_JSON:` line through the shared emitter, which adds the decisions recorded so far, the `error` object and a warning for each step the helper could not finish (`source-tree-not-removed`, `run-lock-not-released`); it never stops on a result. Write each payload value as a JSON string: escape `"` and `\`, and write every path with `/`. Display the line it prints verbatim. When it exits 1 and its message names the payload, fix the payload once and run it again, which redoes nothing already done; when it still fails or prints no line, display the halt message alone. An interactive HALT displays its message and emits nothing. A HALT that names no payload (a helper the frontmatter says to HALT without, resolving to no path) takes `status: "blocked"`, `phase: "re-extract:<the helper's file name>"` and `reason: "<the helper's file name> is missing; re-install SKF"`.
|
|
119
40
|
|
|
120
|
-
|
|
41
|
+
The halt leaves `{run_dir}` in place.
|
|
121
42
|
|
|
122
|
-
**
|
|
123
|
-
|
|
124
|
-
### 0a. Targeted Re-Extraction Branch (Helper — Called from §0 bullet 2)
|
|
125
|
-
|
|
126
|
-
**Do not execute this section sequentially.** It is a helper procedure invoked by §0 bullet 2 when specific conditions are met (see below). Normal-mode runs, and gap-driven runs where every entry has a `source_citation` or qualifies as `Medium`/`Low`/`Info` unknown, skip this section entirely. §0's "skip sections 1–5" instruction does not apply here — §0a is addressed by name from §0, not by sequential fall-through.
|
|
127
|
-
|
|
128
|
-
**Used by:** §0 bullet 2, in either of two cases:
|
|
129
|
-
|
|
130
|
-
- a manifest entry has no `source_citation`, has non-empty `remediation_paths[]`, and `severity` is `Critical` or `High`; **or**
|
|
131
|
-
- a provenance-completeness gap (rule R3 — documented but missing from the provenance-map), routed here **regardless of severity** as long as `source_root` is pinned and readable. For this case, treat the export's documented `source` reference (or `remediation_paths[]` when present) as the path set to scan.
|
|
132
|
-
|
|
133
|
-
**Purpose:** produce AST-backed provenance for citation-less Critical/High gaps so step 6 §3 never writes `source_file: null` for blocking findings. Honors the workflow-level rule **Never hallucinate — every statement must have AST provenance** against the most common gap-driven trigger — a failing test report whose Gap Report `Source:` field is a region reference (e.g., `@storybook/addon-docs control primitives`) rather than a `file:line` pair. Gap-driven mode skips §1 through §5, so §0a is also the only place §1b's source-access and extraction machinery is invoked during gap-driven runs.
|
|
134
|
-
|
|
135
|
-
**Procedure:**
|
|
136
|
-
|
|
137
|
-
1. **Resolve source access** — invoke §1b's MCP-fallback chain (gh API → zread → deepwiki → workspace / ephemeral clone) once per workflow run to ensure files under `{source_root}` are readable. Cache the chosen access path; do not re-resolve per entry.
|
|
138
|
-
2. **Expand `remediation_paths[]`** — for each path across all qualifying entries:
|
|
139
|
-
- Literal source file (ends in a recognized source extension): use as-is.
|
|
140
|
-
- Directory or glob: expand under `{source_root}` using the provenance map's file patterns.
|
|
141
|
-
- **Security boundary:** reject and skip any path that resolves outside `{source_root}`. Remediation text is user-editable and must never be allowed to escape the source tree.
|
|
142
|
-
- Deduplicate the resolved file set across all entries routed to §0a — each physical file is scanned at most once.
|
|
143
|
-
3. **Extract** — run the tier-appropriate extractor from §1b (Quick pattern-match → T1-low; Forge/Forge+/Deep AST via ast-grep → T1) over the resolved file set. Launch subprocesses in parallel (Pattern 4) when available; sequential fallback otherwise. Follow the AST Extraction Protocol in `{extractionPatternsData}` for Forge/Deep tiers, and the tier-degradation rules in `{tierDegradationRulesData}` when AST tools fail on individual files.
|
|
144
|
-
4. **Match by name** — for each manifest entry routed here, search the aggregated extraction results for an export whose `name` matches the manifest entry's `name`. Record the first hit as:
|
|
145
|
-
- `verification: re-extracted`
|
|
146
|
-
- `provenance_citation: {file}:{start_line}` from the AST result
|
|
147
|
-
- `new_location: {file}:{start_line}` (same value — satisfies the existing consumer contract)
|
|
148
|
-
- `resolution_source: remediation-paths`
|
|
149
|
-
- `confidence: T1` (AST-extracted) or `T1-low` (pattern-matched fallback)
|
|
150
|
-
- the full extraction signature (type, params, return_type, docstring) — mirror the shape of §4's per-file extraction record so step 4 Priority 5 can merge it with the same code path used in normal mode.
|
|
151
|
-
|
|
152
|
-
Then apply the §0 bullet 2 **public-reachability gate** to each matched symbol before recording it as a NEW_EXPORT: §0a has full source access, so resolve the symbol's module path and confirm barrel re-export or a fully-`pub` module chain. If it is unreachable (`pub(crate)` / private module), do **not** record `re-extracted` — drop it from the export-bearing set and re-queue the entry as a `metadata update` (rule R4, `reclassified: internal-unreachable`), exactly as the gate specifies. A re-extracted symbol that is not public API is not a documentable NEW_EXPORT. This is a resolution, not an `unresolved[]` failure (step 5) — the symbol was found, just not public — so it does not trigger the Critical/High HALT.
|
|
153
|
-
5. **Track failures across all qualifying entries.** Collect every entry whose symbol was not found in any scanned remediation path into an `unresolved[]` list. After processing every qualifying entry, if `unresolved[]` is non-empty: HALT with a consolidated report listing every unresolved entry (`name`, `severity`, `remediation_paths`, `files_scanned`, `exports_found_in_scan`). Template:
|
|
154
|
-
|
|
155
|
-
```
|
|
156
|
-
Targeted re-extraction failed for {N} Critical/High gap(s).
|
|
157
|
-
|
|
158
|
-
Critical and High gaps must resolve to AST provenance. The Remediation text for
|
|
159
|
-
the entries below does not name a file that contains the expected export, so the
|
|
160
|
-
workflow cannot produce a non-null `source_file` / `source_line` without
|
|
161
|
-
hallucinating.
|
|
162
|
-
|
|
163
|
-
Unresolved entries:
|
|
164
|
-
{for each entry in unresolved[]:}
|
|
165
|
-
- {name} ({severity})
|
|
166
|
-
remediation_paths: {paths}
|
|
167
|
-
files_scanned: {count}
|
|
168
|
-
exports_matched: 0
|
|
169
|
-
|
|
170
|
-
Fix one of the following, then re-run update-skill:
|
|
171
|
-
a) Add a `file:line` citation to the Gap Report `Source:` field.
|
|
172
|
-
b) Edit the Remediation text to name the file(s) that actually contain the export(s).
|
|
173
|
-
c) Downgrade the gap(s) to Medium/Low/Info (accepts the degraded documentation outcome).
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
Exit with status `halted-for-remediation-path`. Step-04 merge has not run; no partial writes. In `{headless_mode}`, emit the halt envelope per SKILL.md §Headless (`error: {phase: "re-extract:targeted-reextraction", reason: "..."}`).
|
|
177
|
-
|
|
178
|
-
6. **Success summary** — record `targeted_reextraction: {resolved_count, files_scanned, exports_matched, tier}` in workflow context. The evidence report (step 6 §4) surfaces this alongside the verified / moved / missing tally.
|
|
179
|
-
|
|
180
|
-
**Why halt instead of degrading to `unknown`:** a Critical or High gap by definition blocks skill usefulness — it is either missing documentation for a public API or a wrong signature. Silently writing `source_file: null` for a blocking gap produces a skill that passes re-test but still hides the broken behavior behind a placeholder. The halt forces the test report to carry usable remediation information — a one-time fix-up that is far cheaper than a downstream audit trying to track why the "repaired" skill still fails.
|
|
43
|
+
**Warnings go to the run log.** Record each warning this step adds to `warnings[]` the moment it is raised: write its text to `{run_dir}/warning.txt` with a file write (a warning can hold quotes, `$` or backticks), then, from `{project-root}`, run `uv run {emitEnvelopeHelper} record --run-dir "{run_dir}" --warning "$(cat "{run_dir}/warning.txt")"`. The halt line and the result line read warnings only from `{run_dir}/warnings.jsonl`.
|
|
181
44
|
|
|
182
45
|
### 1. Check for Docs-Only Mode
|
|
183
46
|
|
|
184
47
|
**If `source_type: "docs-only"` in the original brief or metadata:**
|
|
185
48
|
|
|
186
|
-
"**Docs-only skill detected.** This skill was generated from external documentation, not source code. Re-extraction
|
|
49
|
+
"**Docs-only skill detected.** This skill was generated from external documentation, not source code. Re-extraction re-fetches the documents whose hash changed (step 2 §1) for their updated content."
|
|
187
50
|
|
|
188
|
-
- Re-fetch each URL
|
|
51
|
+
- Re-fetch each URL in `changed_urls` of `{run_dir}/change-manifest.json` using whatever web fetching capability is available; leave every other document as it is
|
|
189
52
|
- Extract updated API information with T3 `[EXT:{url}]` citations
|
|
190
|
-
-
|
|
191
|
-
- Skip
|
|
53
|
+
- Write the updated extraction inventory to `{run_dir}/reextract-records.json`, from which merge and step 5's `apply` work, as `{"mode": "docs-only", "changed_urls": [<the URLs re-fetched>], "exports": [{"name": "<export>", "type": "<kind>", "params": [<each parameter>], "return_type": "<type, or null>", "url": "<the URL it came from>"}]}`
|
|
54
|
+
- Skip sections 1b to 5 (source code extraction), then go straight to §6 (Route to Next Step), whose `dry_run_mode` branch holds for a docs-only skill too: a docs-only `--dry-run` never loads merge.md
|
|
192
55
|
|
|
193
56
|
**If `source_type: "source"` (default):** Continue with source extraction below.
|
|
194
57
|
|
|
195
58
|
### 1b. Determine Extraction Strategy by Tier
|
|
196
59
|
|
|
197
|
-
**
|
|
198
|
-
|
|
199
|
-
**MCP source access (ordered fallback):** When `source_repo` is set in metadata.json, try each MCP tool in order to fetch only the changed files from the change manifest. This avoids clone overhead entirely. Tools are ordered by data freshness — gh API returns live GitHub content and is preferred for update-skill where current file versions are required. zread and deepwiki depend on manual indexing and may return stale data if indexes haven't been refreshed since the changes being extracted.
|
|
200
|
-
|
|
201
|
-
1. **gh API** — `gh api repos/{owner}/{repo}/contents/{path}` for raw file content
|
|
202
|
-
- If accessible: fetch file content (base64-decoded), always current
|
|
203
|
-
- If rate-limited, 404, or inaccessible: log tool and reason, continue to next tool
|
|
204
|
-
2. **zread** — `get_repo_structure` + `read_file` for targeted file access
|
|
205
|
-
- If repo found: fetch changed files, proceed with extraction
|
|
206
|
-
- If "repo not found" or error: log tool and reason, continue to next tool
|
|
207
|
-
- Caveat: indexed data — may be stale if index wasn't refreshed after the target changes
|
|
208
|
-
3. **deepwiki** — `ask_question` for targeted export/signature queries
|
|
209
|
-
- If repo indexed and returns usable source data: extract from response
|
|
210
|
-
- If no results or repo not indexed: log tool and reason, continue to next tool
|
|
211
|
-
- Caveat: returns synthesized content, not raw source — extraction quality varies; index may be stale
|
|
212
|
-
|
|
213
|
-
**Confidence labeling:** MCP-fetched content written to a temp file and analyzed with ast-grep → T1. MCP-fetched content analyzed with pattern matching (AST unavailable) → T1-low.
|
|
60
|
+
**Source access (every tier):** read every changed file from `{source_root}`. When `{source_tree_status}` is `ready` or `offline`, that is the tree init.md §6b prepared at `{target_commit}`, the commit step 2 compared, so detection, extraction, merge and write read one tree; otherwise it is the local source init.md §6 validated. Do not fetch changed files through the gh contents API, zread or deepwiki: the gh contents API serves the default branch unless given a ref, and the zread and deepwiki indexes may sit at another commit, so a citation read there would not point into the commit this update records. If `{source_tree_status}` is `ready` or `offline` and `{source_root}` no longer exists, HALT with status `blocked` per SKILL.md's source-tree rule (halt procedure: `phase: "re-extract:source-tree-missing"`, `path: "{source_root}"`, `reason: "source tree {source_root} disappeared mid-run"`). If one changed file cannot be read, limit its analysis to the provenance-map baseline (State 2: each baseline entry keeps its own confidence label from compilation-time data) and warn: "Could not read {path} from {source_root}. Its analysis is limited to the provenance-map baseline."
|
|
214
61
|
|
|
215
|
-
**
|
|
62
|
+
**What the workers read (every tier):** at each export's line the workers (§2) read what no tool records: its full signature (a function's, a type definition, a constant's value), a class's members and its JSDoc or docstring, and its parameter types and return type only where neither the runner nor `{run_dir}/export-details.json` records them.
|
|
216
63
|
|
|
217
|
-
**
|
|
218
|
-
|
|
219
|
-
**Quick tier (text pattern matching):**
|
|
220
|
-
- Extract function/class/type names via regex patterns
|
|
221
|
-
- Extract export statements via text matching
|
|
222
|
-
- Confidence: T1-low (pattern-matched, not AST-verified)
|
|
64
|
+
**Quick tier (text pattern matching):** step 2 read every listed file by text pattern into `{run_dir}/export-details.json` (T1-low, with `extraction_method: source-read` and `ast_node_type: null`), and §4's helper seeds each record from it.
|
|
223
65
|
|
|
224
66
|
**Forge tier (AST structural extraction):**
|
|
225
67
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
- Extract: function signatures, type definitions, class members, exported constants
|
|
229
|
-
- Extract: parameter types, return types, JSDoc/docstring comments
|
|
230
|
-
- Confidence: T1 (AST-verified structural truth)
|
|
68
|
+
- Step 2's Category B ran the recipe runner (`{extractPublicApiHelper}` `--mode full`, the recipes of the AST Extraction Protocol in `{extractionPatternsData}`) over every file to extract, `{run_dir}/extract-files.json`, and wrote `{run_dir}/extraction.json`: never run it again here. §4's helper takes each file's exports from its `exports[]`, each at the line of its name, never a decorator or `export` line above it: T1 (AST-verified structural truth) with `extraction_method: ast-grep` and the recipe's labels.
|
|
69
|
+
- Read by eye only what the recipes leave out: an export a file defines in a form Known Limitation #11 in `{extractionPatternsData}` lists, a file `file_issues[]` names (not UTF-8, or code the parser could not read, where a recipe can miss an export), a name `entry_point_diff.extraction_gaps[]` lists, and each file step 2 told the user it read by eye. Step 2 already read those of the modified and added files into `{run_dir}/export-details.json` (its entries with an `export_type`), and §4's helper takes them from there. An export read by eye is T1-low with `extraction_method: source-read` and `ast_node_type: null`.
|
|
231
70
|
|
|
232
|
-
**Tier degradation handling (Forge/Forge+/Deep):** If ast-grep
|
|
71
|
+
**Tier degradation handling (Forge/Forge+/Deep):** If step 2's runner could run no ast-grep, or left files unread (step 2 told the user which), follow `{tierDegradationRulesData}` for fallback strategy and user notification requirements. Silent degradation is forbidden: the user must always know which files were read by eye instead of matched, and why.
|
|
233
72
|
|
|
234
73
|
**Deep tier (AST + QMD semantic enrichment):**
|
|
235
|
-
- Perform all Forge tier extractions
|
|
74
|
+
- Perform all Forge tier extractions, labeled by tool as at Forge tier
|
|
236
75
|
- Additionally: launch a subprocess that queries qmd_bridge for temporal context on changed exports, returning T2 evidence per export
|
|
237
76
|
- QMD provides: usage patterns, historical context, related documentation
|
|
238
|
-
- Confidence: T1 for
|
|
77
|
+
- Confidence: structural entries labeled by tool (T1 for an ast-grep match, T1-low for an export read by eye), T2 for semantic enrichment
|
|
239
78
|
|
|
240
|
-
**Tool resolution:** `ast_bridge` →
|
|
79
|
+
**Tool resolution:** `ast_bridge` → `{extractPublicApiHelper}` `--mode full` (step 2), which runs every recipe through the ast-grep CLI; `find_code` only as the fallback of Known Limitation #4, for a recipe that errors or finds nothing where a file clearly holds exports. `qmd_bridge` → QMD MCP tools (`mcp__plugin_qmd-plugin_qmd__search`, `vector_search`) or `qmd` CLI. See `knowledge/tool-resolution.md`.
|
|
241
80
|
|
|
242
81
|
### 2. Extract Changed Files
|
|
243
82
|
|
|
244
|
-
|
|
83
|
+
Step 2's Category A left every promoted or tracked document out of the files to extract (its §2.0): a document must not reach AST extraction, which would produce ghost entries; step 2's Category D and step 4's Priority 6/7 handle doc-type drift.
|
|
245
84
|
|
|
246
|
-
For each
|
|
85
|
+
For each file `{run_dir}/extract-files.json` lists (step 2 wrote it: the MODIFIED and ADDED files and each MOVED file's new path), launch a subprocess that:
|
|
247
86
|
|
|
248
87
|
1. Loads the source file
|
|
249
|
-
2.
|
|
250
|
-
3.
|
|
251
|
-
4. **Return contract.** Each
|
|
88
|
+
2. Takes this file's exports from step 2's `{run_dir}/extraction.json` and `export-details.json` (§1b)
|
|
89
|
+
3. Reads at each export's line what §1b says no tool records
|
|
90
|
+
4. **Return contract.** Each worker returns ONLY this per-file patch, with no prose, no commentary and no markdown fences (the parent strips wrapping fences before parsing), and leaves out a field it has nothing for. Write each patch, as returned, to a file of its own in `{run_dir}/reextract-patches/`, which §4's helper merges into the records it seeds from step 2's files:
|
|
252
91
|
|
|
253
92
|
```json
|
|
254
|
-
{
|
|
255
|
-
"
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
"signature": "...", "location": "{file}:{start_line}-{end_line}",
|
|
259
|
-
"confidence": "T1|T1-low|T2",
|
|
260
|
-
"parameters": [{"name": "...", "type": "..."}],
|
|
261
|
-
"return_type": "...", "docstring": "...",
|
|
262
|
-
"qmd_evidence": "<if Deep tier, else omit>"}
|
|
263
|
-
]
|
|
264
|
-
}
|
|
93
|
+
{"file_path": "...", "exports": [
|
|
94
|
+
{"name": "...", "signature": "<the full signature>", "members": ["<a class's member>"], "docstring": "...",
|
|
95
|
+
"params": ["<name: type>"], "return_type": "..."}
|
|
96
|
+
]}
|
|
265
97
|
```
|
|
266
98
|
|
|
267
99
|
**For DELETED files:** No extraction needed — deletions handled in merge step.
|
|
@@ -270,25 +102,6 @@ For each remaining file in the change manifest with status MODIFIED, ADDED, or R
|
|
|
270
102
|
|
|
271
103
|
**Re-export tracing (Forge/Deep only):** After extracting changed files, check if any public exports from the package entry point (`__init__.py`, `index.ts`, `lib.rs`) are unresolved — particularly when a changed file is part of a module re-export chain. Follow the **Re-Export Tracing** protocol in `{extractionPatternsTracingData}` to trace unresolved symbols to their actual definition files.
|
|
272
104
|
|
|
273
|
-
### 2b. CCC Semantic Ranking (Forge+ and Deep with ccc)
|
|
274
|
-
|
|
275
|
-
**IF `tools.ccc` is true in forge-tier.yaml:**
|
|
276
|
-
|
|
277
|
-
Before aggregating extraction results, use CCC to assess semantic significance of changes:
|
|
278
|
-
|
|
279
|
-
1. Run `ccc_bridge.search("{skill_name}", source_root, top_k=15)` — **Tool resolution:** `/ccc` skill search (Claude Code), ccc MCP (Cursor), `ccc search` (CLI) — to get the skill's most semantically central files
|
|
280
|
-
2. Cross-reference the change manifest files with CCC results
|
|
281
|
-
3. Files appearing in BOTH the change manifest AND CCC's top results are **semantically significant changes** — flag them for priority in the merge step
|
|
282
|
-
4. Store `{ccc_significant_changes: [{file, score}]}` in context
|
|
283
|
-
|
|
284
|
-
This helps the merge step (section 4) prioritize which changes are most likely to affect the skill's core content vs. peripheral modifications.
|
|
285
|
-
|
|
286
|
-
CCC failures: skip ranking silently, all changes treated equally.
|
|
287
|
-
|
|
288
|
-
**Note on remote sources:** If `source_root` is a workspace clone, the CCC index may already exist from a prior forge and can be reused via `ccc search --refresh`. If the source is an ephemeral fallback clone, the clone path is not indexed by CCC — the search returns empty results, so semantic ranking is skipped and all changes are treated equally.
|
|
289
|
-
|
|
290
|
-
**IF `tools.ccc` is false:** Skip this section silently.
|
|
291
|
-
|
|
292
105
|
### 3. Deep Tier QMD Enrichment (Conditional)
|
|
293
106
|
|
|
294
107
|
**ONLY if forge_tier == Deep:**
|
|
@@ -301,59 +114,37 @@ Find the collection entry matching the current skill: look for an entry where `s
|
|
|
301
114
|
Launch a subprocess that loads qmd_bridge and for each changed export:
|
|
302
115
|
1. Queries the `{skill_name}-extraction` collection for semantic context related to the export
|
|
303
116
|
2. Searches for usage patterns, documentation references, temporal history
|
|
304
|
-
3. Returns T2 evidence per export (usage frequency, context snippets, related concepts)
|
|
117
|
+
3. Returns T2 evidence per export (usage frequency, context snippets, related concepts), as patches §4 merges: write one `{"file_path", "exports": [{"name", "qmd_evidence"}]}` block per file to its own file in `{run_dir}/reextract-patches/`
|
|
305
118
|
|
|
306
119
|
**If no matching collection found in registry:**
|
|
307
120
|
Log: "No QMD extraction collection found for {skill_name}. T2 enrichment skipped. Re-run [CS] Create Skill to generate the collection."
|
|
308
|
-
Continue without T2 enrichment
|
|
121
|
+
Continue without T2 enrichment: extraction still produces its structural results, labeled by tool.
|
|
309
122
|
|
|
310
123
|
**If forge_tier != Deep:** Skip this section with notice: "QMD enrichment skipped (tier: {forge_tier})"
|
|
311
124
|
|
|
312
125
|
### 4. Compile Extraction Results
|
|
313
126
|
|
|
314
|
-
|
|
127
|
+
Resolve `{buildChangeManifestHelper}` ← first existing path in `{buildChangeManifestProbeOrder}` and, from `{project-root}`, run:
|
|
315
128
|
|
|
316
|
-
```
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
T2: [count]
|
|
324
|
-
|
|
325
|
-
Per-file extractions:
|
|
326
|
-
{file_path}:
|
|
327
|
-
exports:
|
|
328
|
-
- name: {export_name}
|
|
329
|
-
type: function|class|type|constant
|
|
330
|
-
signature: {full signature}
|
|
331
|
-
location: {file}:{start_line}-{end_line}
|
|
332
|
-
confidence: T1|T1-low|T2
|
|
333
|
-
parameters: [{name, type}]
|
|
334
|
-
return_type: {type}
|
|
335
|
-
docstring: {summary}
|
|
336
|
-
qmd_evidence: {if Deep tier}
|
|
129
|
+
```bash
|
|
130
|
+
uv run {buildChangeManifestHelper} records \
|
|
131
|
+
[--extraction "{run_dir}/extraction.json"] \
|
|
132
|
+
[--export-details "{run_dir}/export-details.json"] \
|
|
133
|
+
--files-from "{run_dir}/extract-files.json" \
|
|
134
|
+
[--patches "{run_dir}/reextract-patches"] \
|
|
135
|
+
-o "{run_dir}/reextract-records.json"
|
|
337
136
|
```
|
|
338
137
|
|
|
339
|
-
|
|
138
|
+
Pass `--extraction` and `--export-details` when step 2 wrote them, and `--patches` when §2 or §3 wrote a patch. It seeds each export's record from step 2's files (name, type, signature, location, labels, return type and `params` in the provenance map's typed form), merges the patches, writes `{run_dir}/reextract-records.json`, where merge and step 5's `apply` read it, and prints `files_extracted`, `exports_extracted` and `confidence_breakdown` (T1, T1-low, T2): never type a record or count one by hand. Add each of its `warnings[]` to `warnings[]`. On exit 1 whose error names a patch file, rewrite that file once in the shape of §2's return contract and run `records` again. On a second exit 1, any other exit 1, no JSON, or no candidate resolves: HALT with status `blocked` (halt procedure: `phase: "re-extract:records"`, its stderr as `reason`).
|
|
340
139
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
| Metric | Count |
|
|
344
|
-
|--------|-------|
|
|
345
|
-
| Files extracted | {count} |
|
|
346
|
-
| Exports extracted | {count} |
|
|
347
|
-
| T1 (AST-verified) | {count} |
|
|
348
|
-
| T1-low (pattern-matched) | {count} |
|
|
349
|
-
| T2 (QMD-enriched) | {count} |
|
|
140
|
+
### 5. Display Extraction Summary and Auto-Proceed
|
|
350
141
|
|
|
351
|
-
**
|
|
142
|
+
Display one line from §4's results: "**Re-extracted** {exports} exports from {files} files ({t1} T1, {t1_low} T1-low, {t2} T2)." The report (step 6) shows the confidence tier breakdown.
|
|
352
143
|
|
|
353
144
|
### 6. Route to Next Step
|
|
354
145
|
|
|
355
146
|
This step auto-proceeds — no user choices. Once all changed files are extracted and results compiled, load and fully read the next file, then execute it, per the branch that applies:
|
|
356
147
|
|
|
357
|
-
- **`dry_run_mode == true`** → display "**Dry-run mode
|
|
148
|
+
- **`dry_run_mode == true`** → display "**Dry-run mode: skipping merge and write.** Loading report..." and load `report.md` (NOT `{nextStepFile}`); it emits status `dry-run` describing what merge+write would have done. Every route out of this step comes here, the docs-only one (§1) included, so no artifact is modified on disk by this run.
|
|
358
149
|
- **Otherwise** → display "**Proceeding to merge...**" and load `{nextStepFile}` (merge.md) to begin the merge operation.
|
|
359
150
|
|