bmad-module-skill-forge 1.4.0 → 1.5.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 +0 -8
- package/docs/_data/pinned.yaml +1 -1
- package/docs/_internal/STABILITY.md +1 -1
- package/docs/architecture.md +2 -2
- package/docs/examples.md +1 -1
- package/docs/workflows.md +5 -5
- package/package.json +2 -2
- package/src/README.md +1 -1
- package/src/knowledge/ccc-bridge.md +12 -12
- package/src/knowledge/qmd-registry.md +5 -5
- package/src/shared/health-check.md +5 -5
- package/src/shared/references/description-guard-protocol.md +100 -0
- package/src/shared/references/output-contract-schema.md +1 -1
- package/src/shared/scripts/schemas/skf-brief-result-envelope.v1.json +6 -6
- package/src/shared/scripts/schemas/skf-setup-result-envelope.v1.json +9 -3
- package/src/shared/scripts/schemas/skf-update-result-envelope.v1.json +149 -0
- package/src/shared/scripts/schemas/skill-brief.v1.json +22 -2
- package/src/shared/scripts/skf-build-change-manifest.py +420 -0
- package/src/shared/scripts/skf-check-workspace-drift.py +321 -0
- package/src/shared/scripts/skf-compare-file-hashes.py +357 -0
- package/src/shared/scripts/skf-description-guard.py +359 -0
- package/src/shared/scripts/skf-detect-language.py +2 -2
- package/src/shared/scripts/skf-detect-scripts-assets.py +613 -0
- package/src/shared/scripts/skf-detect-tools.py +97 -8
- package/src/shared/scripts/skf-detect-workspaces.py +1 -1
- package/src/shared/scripts/skf-disqualify-candidates.py +576 -0
- package/src/shared/scripts/skf-emit-brief-result-envelope.py +3 -3
- package/src/shared/scripts/skf-emit-result-envelope.py +93 -9
- package/src/shared/scripts/skf-enumerate-stack-skills.py +514 -0
- package/src/shared/scripts/skf-forge-tier-rw.py +11 -11
- package/src/shared/scripts/skf-hash-content.py +284 -0
- package/src/shared/scripts/skf-load-provenance.py +295 -0
- package/src/shared/scripts/skf-merge-ccc-exclusions.py +45 -1
- package/src/shared/scripts/skf-pair-intersect.py +250 -0
- package/src/shared/scripts/skf-provenance-gap-dispatch.py +433 -0
- package/src/shared/scripts/skf-qmd-classify-collections.py +42 -8
- package/src/shared/scripts/skf-recommend-scope-type.py +2 -2
- package/src/shared/scripts/skf-render-quick-metadata.py +2 -2
- package/src/shared/scripts/skf-resolve-authoritative-files.py +504 -0
- package/src/shared/scripts/skf-scan-manifests.py +738 -0
- package/src/shared/scripts/skf-scan-skill-md-structure.py +375 -0
- package/src/shared/scripts/skf-update-active-symlink.py +315 -0
- package/src/shared/scripts/skf-validate-brief-inputs.py +5 -5
- package/src/shared/scripts/skf-validate-brief-schema.py +348 -0
- package/src/shared/scripts/skf-write-skill-brief.py +61 -5
- package/src/skf-analyze-source/SKILL.md +69 -16
- package/src/skf-analyze-source/assets/skill-brief-schema.md +1 -1
- package/src/skf-analyze-source/customize.toml +55 -0
- package/src/skf-analyze-source/{steps-c/step-01b-continue.md → references/continue.md} +12 -12
- package/src/skf-analyze-source/{steps-c/step-06-generate-briefs.md → references/generate-briefs.md} +29 -10
- package/src/skf-analyze-source/{steps-c/step-07-health-check.md → references/health-check.md} +5 -3
- package/src/skf-analyze-source/{steps-c/step-03-identify-units.md → references/identify-units.md} +44 -14
- package/src/skf-analyze-source/{steps-c/step-01-init.md → references/init.md} +27 -6
- package/src/skf-analyze-source/{steps-c/step-04-map-and-detect.md → references/map-and-detect.md} +52 -25
- package/src/skf-analyze-source/{steps-c/step-05-recommend.md → references/recommend.md} +15 -8
- package/src/skf-analyze-source/{steps-c/step-02-scan-project.md → references/scan-project.md} +12 -10
- package/src/skf-analyze-source/references/unit-detection-heuristics.md +2 -0
- package/src/skf-analyze-source/templates/analysis-report-template.md +6 -6
- package/src/skf-audit-skill/SKILL.md +66 -15
- package/src/skf-audit-skill/assets/drift-report-template.md +6 -5
- package/src/skf-audit-skill/customize.toml +49 -0
- package/src/skf-audit-skill/{steps-c/step-07-health-check.md → references/health-check.md} +5 -3
- package/src/skf-audit-skill/references/init.md +305 -0
- package/src/skf-audit-skill/{steps-c/step-02-re-index.md → references/re-index.md} +11 -11
- package/src/skf-audit-skill/{steps-c/step-06-report.md → references/report.md} +25 -7
- package/src/skf-audit-skill/{steps-c/step-04-semantic-diff.md → references/semantic-diff.md} +6 -6
- package/src/skf-audit-skill/{steps-c/step-05-severity-classify.md → references/severity-classify.md} +5 -5
- package/src/skf-audit-skill/references/severity-rules.md +2 -0
- package/src/skf-audit-skill/{steps-c/step-03-structural-diff.md → references/structural-diff.md} +29 -16
- package/src/skf-brief-skill/SKILL.md +48 -18
- package/src/skf-brief-skill/assets/description-voice-examples.md +1 -1
- package/src/skf-brief-skill/assets/skill-brief-schema.md +32 -2
- package/src/skf-brief-skill/customize.toml +44 -0
- package/src/skf-brief-skill/{steps-c/step-02-analyze-target.md → references/analyze-target.md} +5 -5
- package/src/skf-brief-skill/{steps-c/step-04-confirm-brief.md → references/confirm-brief.md} +13 -10
- package/src/skf-brief-skill/references/draft-checkpoint.md +4 -4
- package/src/skf-brief-skill/{steps-c/step-01-gather-intent.md → references/gather-intent.md} +24 -24
- package/src/skf-brief-skill/references/headless-args.md +9 -9
- package/src/skf-brief-skill/references/headless-source-authority-detection.md +1 -1
- package/src/skf-brief-skill/{steps-c/step-06-health-check.md → references/health-check.md} +4 -2
- package/src/skf-brief-skill/references/portfolio-similarity-check.md +2 -2
- package/src/skf-brief-skill/references/qmd-collection-registration.md +1 -1
- package/src/skf-brief-skill/{steps-c/step-03-scope-definition.md → references/scope-definition.md} +19 -16
- package/src/skf-brief-skill/references/version-resolution.md +2 -2
- package/src/skf-brief-skill/{steps-c/step-05-write-brief.md → references/write-brief.md} +11 -10
- package/src/skf-create-skill/SKILL.md +25 -19
- package/src/skf-create-skill/assets/compile-assembly-rules.md +3 -3
- package/src/skf-create-skill/assets/skill-sections.md +5 -5
- package/src/skf-create-skill/assets/tessl-dismissal-rules.md +11 -11
- package/src/skf-create-skill/customize.toml +35 -0
- package/src/skf-create-skill/references/authoritative-files-protocol.md +142 -0
- package/src/skf-create-skill/{steps-c/step-05-compile.md → references/compile.md} +16 -16
- package/src/skf-create-skill/{steps-c/step-03d-component-extraction.md → references/component-extraction.md} +16 -16
- package/src/skf-create-skill/{steps-c/step-02-ecosystem-check.md → references/ecosystem-check.md} +4 -4
- package/src/skf-create-skill/{steps-c/step-04-enrich.md → references/enrich.md} +3 -3
- package/src/skf-create-skill/{steps-c/step-03-extract.md → references/extract.md} +52 -120
- package/src/skf-create-skill/references/extraction-patterns.md +8 -8
- package/src/skf-create-skill/{steps-c/step-07-generate-artifacts.md → references/generate-artifacts.md} +17 -9
- package/src/skf-create-skill/{steps-c/step-09-health-check.md → references/health-check.md} +4 -2
- package/src/skf-create-skill/{steps-c/step-01-load-brief.md → references/load-brief.md} +40 -32
- package/src/skf-create-skill/{steps-c/step-08-report.md → references/report.md} +8 -8
- package/src/skf-create-skill/references/source-resolution-protocols.md +6 -6
- package/src/skf-create-skill/{steps-c/sub/step-02b-ccc-discover.md → references/sub/ccc-discover.md} +5 -5
- package/src/skf-create-skill/{steps-c/sub/step-03c-fetch-docs.md → references/sub/fetch-docs.md} +28 -12
- package/src/skf-create-skill/{steps-c/sub/step-03b-fetch-temporal.md → references/sub/fetch-temporal.md} +81 -50
- package/src/skf-create-skill/{steps-c/step-06-validate.md → references/validate.md} +46 -26
- package/src/skf-create-stack-skill/SKILL.md +76 -17
- package/src/skf-create-stack-skill/assets/provenance-map-schema.md +102 -0
- package/src/skf-create-stack-skill/assets/stack-skill-template.md +1 -1
- package/src/skf-create-stack-skill/customize.toml +46 -0
- package/src/skf-create-stack-skill/{steps-c/step-06-compile-stack.md → references/compile-stack.md} +6 -5
- package/src/skf-create-stack-skill/references/compose-mode-rules.md +3 -1
- package/src/skf-create-stack-skill/{steps-c/step-05-detect-integrations.md → references/detect-integrations.md} +32 -11
- package/src/skf-create-stack-skill/{steps-c/step-02-detect-manifests.md → references/detect-manifests.md} +28 -28
- package/src/skf-create-stack-skill/{steps-c/step-07-generate-output.md → references/generate-output.md} +11 -85
- package/src/skf-create-stack-skill/{steps-c/step-10-health-check.md → references/health-check.md} +4 -2
- package/src/skf-create-stack-skill/{steps-c/step-01-init.md → references/init.md} +70 -4
- package/src/skf-create-stack-skill/references/integration-patterns.md +2 -0
- package/src/skf-create-stack-skill/references/manifest-patterns.md +2 -0
- package/src/skf-create-stack-skill/{steps-c/step-04-parallel-extract.md → references/parallel-extract.md} +40 -17
- package/src/skf-create-stack-skill/{steps-c/step-03-rank-and-confirm.md → references/rank-and-confirm.md} +5 -4
- package/src/skf-create-stack-skill/{steps-c/step-09-report.md → references/report.md} +3 -3
- package/src/skf-create-stack-skill/{steps-c/step-08-validate.md → references/validate.md} +6 -6
- package/src/skf-drop-skill/SKILL.md +84 -12
- package/src/skf-drop-skill/customize.toml +57 -0
- package/src/skf-drop-skill/{steps-c/step-02-execute.md → references/execute.md} +49 -34
- package/src/skf-drop-skill/{steps-c/step-04-health-check.md → references/health-check.md} +6 -4
- package/src/skf-drop-skill/{steps-c/step-03-report.md → references/report.md} +13 -5
- package/src/skf-drop-skill/{steps-c/step-01-select.md → references/select.md} +63 -15
- package/src/skf-export-skill/SKILL.md +85 -16
- package/src/skf-export-skill/assets/managed-section-format.md +3 -3
- package/src/skf-export-skill/assets/snippet-format.md +2 -2
- package/src/skf-export-skill/customize.toml +49 -0
- package/src/skf-export-skill/{steps-c/step-03-generate-snippet.md → references/generate-snippet.md} +18 -12
- package/src/skf-export-skill/{steps-c/step-07-health-check.md → references/health-check.md} +6 -4
- package/src/skf-export-skill/{steps-c/step-01-load-skill.md → references/load-skill.md} +21 -51
- package/src/skf-export-skill/references/manifest-rebuild.md +68 -0
- package/src/skf-export-skill/references/multi-skill-mode.md +38 -0
- package/src/skf-export-skill/references/orphan-context-detection.md +75 -0
- package/src/skf-export-skill/references/orphan-row-detection.md +102 -0
- package/src/skf-export-skill/{steps-c/step-02-package.md → references/package.md} +7 -7
- package/src/skf-export-skill/references/preflight-snippet-root-probe.md +74 -0
- package/src/skf-export-skill/{steps-c/step-06-summary.md → references/summary.md} +30 -6
- package/src/skf-export-skill/{steps-c/step-05-token-report.md → references/token-report.md} +5 -5
- package/src/skf-export-skill/{steps-c/step-04-update-context.md → references/update-context.md} +116 -91
- package/src/skf-quick-skill/SKILL.md +63 -123
- package/src/skf-quick-skill/customize.toml +44 -0
- package/src/skf-quick-skill/references/batch-mode.md +102 -0
- package/src/skf-quick-skill/{steps-c/step-04-compile.md → references/compile.md} +10 -10
- package/src/skf-quick-skill/{steps-c/step-02-ecosystem-check.md → references/ecosystem-check.md} +5 -5
- package/src/skf-quick-skill/{steps-c/step-06-finalize.md → references/finalize.md} +7 -7
- package/src/skf-quick-skill/{steps-c/step-07-health-check.md → references/health-check.md} +3 -3
- package/src/skf-quick-skill/{steps-c/step-03-quick-extract.md → references/quick-extract.md} +5 -5
- package/src/skf-quick-skill/references/registry-resolution.md +2 -0
- package/src/skf-quick-skill/{steps-c/step-01-resolve-target.md → references/resolve-target.md} +14 -10
- package/src/skf-quick-skill/{steps-c/step-05-write-and-validate.md → references/write-and-validate.md} +4 -4
- package/src/skf-refine-architecture/SKILL.md +86 -16
- package/src/skf-refine-architecture/customize.toml +49 -0
- package/src/skf-refine-architecture/{steps-c/step-05-compile.md → references/compile.md} +4 -4
- package/src/skf-refine-architecture/{steps-c/step-02-gap-analysis.md → references/gap-analysis.md} +5 -5
- package/src/skf-refine-architecture/{steps-c/step-07-health-check.md → references/health-check.md} +6 -4
- package/src/skf-refine-architecture/{steps-c/step-04-improvements.md → references/improvements.md} +5 -5
- package/src/skf-refine-architecture/references/init.md +144 -0
- package/src/skf-refine-architecture/{steps-c/step-03-issue-detection.md → references/issue-detection.md} +5 -5
- package/src/skf-refine-architecture/references/refinement-rules.md +2 -0
- package/src/skf-refine-architecture/{steps-c/step-06-report.md → references/report.md} +14 -5
- package/src/skf-rename-skill/SKILL.md +82 -12
- package/src/skf-rename-skill/customize.toml +52 -0
- package/src/skf-rename-skill/{steps-c/step-02-execute.md → references/execute.md} +94 -99
- package/src/skf-rename-skill/references/health-check.md +30 -0
- package/src/skf-rename-skill/references/rebuild-context.md +110 -0
- package/src/skf-rename-skill/{steps-c/step-03-report.md → references/report.md} +13 -5
- package/src/skf-rename-skill/{steps-c/step-01-select.md → references/select.md} +59 -20
- package/src/skf-setup/SKILL.md +35 -35
- package/src/skf-setup/customize.toml +33 -0
- package/src/skf-setup/{steps-c/step-03-auto-index.md → references/auto-index.md} +10 -18
- package/src/skf-setup/{steps-c/step-01b-ccc-index.md → references/ccc-index.md} +14 -22
- package/src/skf-setup/{steps-c/step-01-detect-and-tier.md → references/detect-and-tier.md} +23 -10
- package/src/skf-setup/{steps-c/step-05-health-check.md → references/health-check.md} +1 -1
- package/src/skf-setup/{steps-c/step-04-report.md → references/report.md} +21 -19
- package/src/skf-setup/references/tier-rules.md +1 -1
- package/src/skf-setup/{steps-c/step-02-write-config.md → references/write-config.md} +14 -13
- package/src/skf-test-skill/SKILL.md +77 -15
- package/src/skf-test-skill/customize.toml +54 -0
- package/src/skf-test-skill/{steps-c/step-04-coherence-check.md → references/coherence-check.md} +28 -71
- package/src/skf-test-skill/{steps-c/step-03-coverage-check.md → references/coverage-check.md} +16 -39
- package/src/skf-test-skill/{steps-c/step-02-detect-mode.md → references/detect-mode.md} +4 -26
- package/src/skf-test-skill/{steps-c/step-04b-external-validators.md → references/external-validators.md} +6 -28
- package/src/skf-test-skill/references/health-check.md +14 -0
- package/src/skf-test-skill/{steps-c/step-01-init.md → references/init.md} +21 -37
- package/src/skf-test-skill/references/migration-section-rules.md +4 -2
- package/src/skf-test-skill/{steps-c/step-06-report.md → references/report.md} +41 -51
- package/src/skf-test-skill/{steps-c/step-05-score.md → references/score.md} +26 -43
- package/src/skf-test-skill/references/scoring-rules.md +8 -6
- package/src/skf-test-skill/references/source-access-protocol.md +7 -5
- package/src/skf-test-skill/scripts/compute-score.py +88 -17
- package/src/skf-test-skill/templates/test-report-template.md +13 -13
- package/src/skf-update-skill/SKILL.md +23 -14
- package/src/skf-update-skill/customize.toml +44 -0
- package/src/skf-update-skill/{steps-c/step-02-detect-changes.md → references/detect-changes.md} +176 -68
- package/src/skf-update-skill/references/health-check.md +32 -0
- package/src/skf-update-skill/{steps-c/step-01-init.md → references/init.md} +56 -8
- package/src/skf-update-skill/references/manual-section-rules.md +4 -0
- package/src/skf-update-skill/references/merge-conflict-rules.md +4 -0
- package/src/skf-update-skill/{steps-c/step-04-merge.md → references/merge.md} +8 -8
- package/src/skf-update-skill/{steps-c/step-03-re-extract.md → references/re-extract.md} +53 -44
- package/src/skf-update-skill/references/remote-source-resolution.md +5 -1
- package/src/skf-update-skill/references/report.md +214 -0
- package/src/skf-update-skill/{steps-c/step-05-validate.md → references/validate.md} +5 -5
- package/src/skf-update-skill/{steps-c/step-06-write.md → references/write.md} +73 -51
- package/src/skf-verify-stack/SKILL.md +89 -17
- package/src/skf-verify-stack/assets/feasibility-report-template.md +4 -4
- package/src/skf-verify-stack/customize.toml +50 -0
- package/src/skf-verify-stack/references/coverage-patterns.md +2 -2
- package/src/skf-verify-stack/{steps-c/step-02-coverage.md → references/coverage.md} +7 -7
- package/src/skf-verify-stack/{steps-c/step-07-health-check.md → references/health-check.md} +7 -5
- package/src/skf-verify-stack/references/init.md +166 -0
- package/src/skf-verify-stack/references/integration-verification-rules.md +1 -1
- package/src/skf-verify-stack/{steps-c/step-03-integrations.md → references/integrations.md} +12 -12
- package/src/skf-verify-stack/{steps-c/step-06-report.md → references/report.md} +22 -41
- package/src/skf-verify-stack/{steps-c/step-04-requirements.md → references/requirements.md} +7 -7
- package/src/skf-verify-stack/{steps-c/step-05-synthesize.md → references/synthesize.md} +8 -8
- package/tools/validate-docs-drift.js +1 -1
- package/src/skf-audit-skill/steps-c/step-01-init.md +0 -221
- package/src/skf-refine-architecture/steps-c/step-01-init.md +0 -136
- package/src/skf-rename-skill/steps-c/step-04-health-check.md +0 -22
- package/src/skf-test-skill/steps-c/step-07-health-check.md +0 -25
- package/src/skf-update-skill/steps-c/step-07-report.md +0 -148
- package/src/skf-update-skill/steps-c/step-08-health-check.md +0 -22
- package/src/skf-verify-stack/steps-c/step-01-init.md +0 -178
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
---
|
|
2
|
-
nextStepFile: '
|
|
2
|
+
nextStepFile: 'detect-changes.md'
|
|
3
3
|
manualSectionRulesFile: 'references/manual-section-rules.md'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
+
<!-- Config: communicate in {communication_language}. -->
|
|
7
|
+
|
|
6
8
|
# Step 1: Initialize Update
|
|
7
9
|
|
|
8
10
|
## STEP GOAL:
|
|
@@ -16,8 +18,6 @@ Load the existing skill and all its provenance data, detect whether this is an i
|
|
|
16
18
|
|
|
17
19
|
## MANDATORY SEQUENCE
|
|
18
20
|
|
|
19
|
-
**CRITICAL:** Follow this sequence exactly. Do not skip, reorder, or improvise unless user explicitly requests a change.
|
|
20
|
-
|
|
21
21
|
### 1. Request Skill Path
|
|
22
22
|
|
|
23
23
|
"**Which skill would you like to update?**
|
|
@@ -26,7 +26,9 @@ Provide either:
|
|
|
26
26
|
- A skill name (resolves via version-aware path resolution — see `knowledge/version-paths.md`)
|
|
27
27
|
- A full path to the skill folder
|
|
28
28
|
- A skill name with `--from-test-report` to use the test report's gap findings instead of source drift detection
|
|
29
|
-
- `--allow-workspace-drift` (gap-driven mode only) to intentionally bypass the step
|
|
29
|
+
- `--allow-workspace-drift` (gap-driven mode only) to intentionally bypass the step 3 §0.a guard that halts when the local workspace HEAD does not match `metadata.source_commit`. Only use this if you know the spot-checks should read the current workspace instead of the pinned tree — step 6 will NOT automatically re-pin
|
|
30
|
+
- `--detect-only` to run detect-changes only and exit; emits the change manifest with no further work and no writes
|
|
31
|
+
- `--dry-run` to run detect-changes + re-extract and exit before merge/write; emits what WOULD change without modifying any artifact
|
|
30
32
|
|
|
31
33
|
**Skill:** {user provides path or name}"
|
|
32
34
|
|
|
@@ -42,7 +44,53 @@ Resolve the path to an absolute skill folder location.
|
|
|
42
44
|
**If `--from-test-report` was provided (or user references a test report):**
|
|
43
45
|
Search for the test report at `{forge_data_folder}/{skill_name}/{active_version}/test-report-{skill_name}.md` (i.e., `{forge_version}/test-report-{skill_name}.md`). If not found at the versioned path, fall back to `{forge_data_folder}/{skill_name}/test-report-{skill_name}.md`. If found, set `test_report_path` in context and `update_mode: gap-driven`. If not found at either path, warn and continue with normal source drift mode.
|
|
44
46
|
|
|
45
|
-
**If `--allow-workspace-drift` was provided:** set `allow_workspace_drift: true` in workflow context. This flag is consumed by step
|
|
47
|
+
**If `--allow-workspace-drift` was provided:** set `allow_workspace_drift: true` in workflow context. This flag is consumed by step 3 §0.a's pre-flight drift guard (gap-driven mode only) and has no effect in normal source-drift mode.
|
|
48
|
+
|
|
49
|
+
**If `--detect-only` was provided:** set `detect_only_mode: true` in workflow context. After step 2 (detect-changes) completes, jump directly to step 7 (report) — skip re-extract, merge, validate, and write. The report emits the change manifest and a `SKF_UPDATE_RESULT_JSON` envelope with `status: "detect-only"`. **Compatibility:** `--detect-only` short-circuits before §0.a runs, so `--allow-workspace-drift` is silently ignored in detect-only mode (warn the user once at flag-parse time: "`--allow-workspace-drift` has no effect with `--detect-only` — workspace drift guard runs in step 3 §0.a, which is skipped").
|
|
50
|
+
|
|
51
|
+
**If `--dry-run` was provided:** set `dry_run_mode: true` in workflow context. After step 3 (re-extract) completes, jump directly to step 7 (report) — skip merge, validate, and write. The report emits what would change with `status: "dry-run"` in the envelope. No artifact on disk is modified — `--dry-run` is the "show me what an update would do without committing" mode.
|
|
52
|
+
|
|
53
|
+
**If BOTH `--detect-only` AND `--dry-run` were provided:** `--detect-only` wins (it's the more restrictive). Warn the user once: "`--detect-only` supersedes `--dry-run`; re-extract is skipped." Set `detect_only_mode: true`, ignore `dry_run_mode`.
|
|
54
|
+
|
|
55
|
+
### 1b. Concurrency Guard
|
|
56
|
+
|
|
57
|
+
**Skip this section entirely if `detect_only_mode` OR `dry_run_mode` is true.** Both inspection modes are read-only — they do not modify any artifact and are safe to run alongside a concurrent real update.
|
|
58
|
+
|
|
59
|
+
Two concurrent `skf-update-skill` runs against the same `{forge_data_folder}/{skill_name}/` can corrupt provenance: one would write metadata.json mid-way through the other's extraction. The lock below catches the common accidental-double-invoke case (user re-runs in another shell before the first finishes). It is a **best-effort PID-file guard**, not a held flock — the LLM-driven workflow spans many turn boundaries and no single bash invocation can hold flock across them. Use the pattern from `skf-create-skill/references/source-resolution-protocols.md:87` (workspace concurrency guard) as the conceptual model.
|
|
60
|
+
|
|
61
|
+
**Mirror this exactly so the guard works the same way every run:**
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# Lock file path — one per skill, lives next to skill-brief.yaml
|
|
65
|
+
LOCK={forge_data_folder}/{skill_name}/.skf-update.lock
|
|
66
|
+
mkdir -p "$(dirname "$LOCK")"
|
|
67
|
+
|
|
68
|
+
if [ -f "$LOCK" ]; then
|
|
69
|
+
HELD_PID=$(head -n1 "$LOCK" 2>/dev/null | awk '{print $1}')
|
|
70
|
+
if [ -n "$HELD_PID" ] && kill -0 "$HELD_PID" 2>/dev/null; then
|
|
71
|
+
# Live PID — another update is running. HALT.
|
|
72
|
+
echo "skf-update-skill: another update is in progress (pid=$HELD_PID, started $(awk 'NR==2' "$LOCK" 2>/dev/null))"
|
|
73
|
+
# (LLM emits SKF_UPDATE_RESULT_JSON status=halted-for-concurrent-run, see below)
|
|
74
|
+
exit 1
|
|
75
|
+
fi
|
|
76
|
+
# Stale lock (PID is dead) — log + overwrite
|
|
77
|
+
echo "skf-update-skill: clearing stale lock from pid=$HELD_PID"
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
# Acquire: write our PID + start timestamp (one per line)
|
|
81
|
+
printf '%s\n%s\n' "$$" "$(date -u +%Y-%m-%dT%H:%M:%SZ)" > "$LOCK"
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**Halt protocol on live-PID collision:**
|
|
85
|
+
|
|
86
|
+
- Display: `"**Another update is in progress.** The skill {skill_name} is locked by pid={HELD_PID} (started {timestamp from line 2 of the lock file}). Wait for that run to finish, or — if you know that pid is no longer running — delete {LOCK} manually and re-run."`
|
|
87
|
+
- In `{headless_mode}`, emit `SKF_UPDATE_RESULT_JSON` with `status: "halted-for-concurrent-run"`, `error: {phase: "init:concurrency-guard", path: "{LOCK}", reason: "another update in progress (pid={HELD_PID})"}`, and exit immediately. **No `headless_decisions[]` entry** — this is a hard halt before any gate fires.
|
|
88
|
+
|
|
89
|
+
**Release contract:**
|
|
90
|
+
|
|
91
|
+
- The terminal health-check step (step 8) deletes the lock file as its final action.
|
|
92
|
+
- **Every halted-for-\* path in this workflow must delete the lock before exiting** — otherwise the next attempt would see a stale lock from this run. The lock-release is a single `rm -f "$LOCK"` per halt site; do not skip it.
|
|
93
|
+
- The lock is best-effort: a crash mid-workflow (process kill, host reboot) leaves a stale lock that the next run will clear via the live-PID check above. No manual cleanup needed in the common case.
|
|
46
94
|
|
|
47
95
|
### 2. Validate Required Artifacts
|
|
48
96
|
|
|
@@ -68,7 +116,7 @@ After loading metadata.json, check `skill_type`:
|
|
|
68
116
|
**To update this stack skill**, run `skf-create-stack-skill` with the same project path. It will re-analyze manifests (code-mode) or re-read constituent skills (compose-mode) and produce an updated stack.
|
|
69
117
|
|
|
70
118
|
If you came here from an audit report, the drift report identifies which constituent libraries changed — use that to decide whether re-composition is needed."
|
|
71
|
-
- Exit the workflow (do not proceed to step
|
|
119
|
+
- Exit the workflow (do not proceed to step 2)
|
|
72
120
|
|
|
73
121
|
### 3. Load Forge Tier Configuration
|
|
74
122
|
|
|
@@ -127,7 +175,7 @@ Load {manualSectionRulesFile} to understand [MANUAL] detection patterns.
|
|
|
127
175
|
|
|
128
176
|
"**Source path from provenance map is invalid:** `{source_root}`
|
|
129
177
|
|
|
130
|
-
|
|
178
|
+
Provide the current source code path:
|
|
131
179
|
**Path:** {user provides path}"
|
|
132
180
|
|
|
133
181
|
### 7. Present Baseline Summary
|
|
@@ -166,7 +214,7 @@ Display: "**Select:** [C] Continue to Change Detection"
|
|
|
166
214
|
#### EXECUTION RULES:
|
|
167
215
|
|
|
168
216
|
- ALWAYS halt and wait for user input after presenting menu
|
|
169
|
-
- **GATE [default: C]** — If `{headless_mode}`: auto-proceed with [C] Continue, log: "headless: auto-continue past update confirmation"
|
|
217
|
+
- **GATE [default: C]** — If `{headless_mode}`: auto-proceed with [C] Continue, log: "headless: auto-continue past update confirmation". **Also append to in-context `headless_decisions[]`** (step 7 surfaces this list in `SKF_UPDATE_RESULT_JSON`): `{gate: "init.update-confirmation", default_action: "C", taken_action: "C", reason: "headless: no user to prompt"}`. The headless_decisions[] array is the structured audit trail for non-interactive runs — see `src/shared/scripts/schemas/skf-update-result-envelope.v1.json` for the entry shape.
|
|
170
218
|
- ONLY proceed to next step when user selects 'C'
|
|
171
219
|
|
|
172
220
|
## CRITICAL STEP COMPLETION NOTE
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
---
|
|
2
|
-
nextStepFile: '
|
|
2
|
+
nextStepFile: 'validate.md'
|
|
3
3
|
manualSectionRulesFile: 'references/manual-section-rules.md'
|
|
4
4
|
mergeConflictRulesFile: 'references/merge-conflict-rules.md'
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
<!-- Config: communicate in {communication_language}. -->
|
|
8
|
+
|
|
7
9
|
# Step 4: Merge
|
|
8
10
|
|
|
9
11
|
## STEP GOAL:
|
|
@@ -19,8 +21,6 @@ Merge freshly extracted export data into the existing SKILL.md content while pre
|
|
|
19
21
|
|
|
20
22
|
## MANDATORY SEQUENCE
|
|
21
23
|
|
|
22
|
-
**CRITICAL:** Follow this sequence exactly. Do not skip, reorder, or improvise unless user explicitly requests a change.
|
|
23
|
-
|
|
24
24
|
### 1. Load Merge Rules
|
|
25
25
|
|
|
26
26
|
Load {manualSectionRulesFile} for [MANUAL] detection and preservation patterns.
|
|
@@ -165,7 +165,7 @@ Write the merged content produced by sections 3–5 directly to disk now. Later
|
|
|
165
165
|
**Write SKILL.md:**
|
|
166
166
|
- Use the `Edit` or `Write` tool to write merged SKILL.md content to `{skill_package}/SKILL.md`
|
|
167
167
|
- Preserve UTF-8 encoding
|
|
168
|
-
- If the source version detected during step
|
|
168
|
+
- If the source version detected during step 3 differs from the previous metadata version, create the new `{skill_package}` directory (`{skill_group}/{new_version}/`) first and write there — the previous version's directory is preserved on disk. Update `{skill_package}` in context to point at the new path.
|
|
169
169
|
|
|
170
170
|
**Write stack reference files (if `skill_type == "stack"`):**
|
|
171
171
|
- For each affected file from section 5, use `Edit` or `Write` to write:
|
|
@@ -174,10 +174,10 @@ Write the merged content produced by sections 3–5 directly to disk now. Later
|
|
|
174
174
|
- Preserve [MANUAL] blocks exactly as captured in section 2.
|
|
175
175
|
|
|
176
176
|
**Do NOT write here:**
|
|
177
|
-
- `metadata.json`, `provenance-map.json`, `evidence-report.md` — derived from merge + validation output, written by step
|
|
178
|
-
- `context-snippet.md` — regenerated from the on-disk SKILL.md + metadata.json by step
|
|
177
|
+
- `metadata.json`, `provenance-map.json`, `evidence-report.md` — derived from merge + validation output, written by step 6 sections 2–4
|
|
178
|
+
- `context-snippet.md` — regenerated from the on-disk SKILL.md + metadata.json by step 6 section 5
|
|
179
179
|
|
|
180
|
-
**Halt-on-tool-failure:** If any `Edit`/`Write` call errors (permission denied, disk full, path invalid, etc.), halt and report the failure — do not proceed to step
|
|
180
|
+
**Halt-on-tool-failure:** If any `Edit`/`Write` call errors (permission denied, disk full, path invalid, etc.), halt and report the failure — do not proceed to step 5 validation. The skill package may be in a partial state and will need manual recovery before re-running update-skill.
|
|
181
181
|
|
|
182
182
|
### 7. Display Merge Summary
|
|
183
183
|
|
|
@@ -205,7 +205,7 @@ Display: "**Merge complete with conflict resolution. Select:** [C] Continue to V
|
|
|
205
205
|
#### EXECUTION RULES:
|
|
206
206
|
|
|
207
207
|
- ALWAYS halt and wait for user input after conflict resolution
|
|
208
|
-
- **GATE [default: C if clean merge]** — If `{headless_mode}` and merge is clean (no [MANUAL] conflicts): auto-proceed with [C] Continue, log: "headless: clean merge, auto-continue". If conflicts exist, HALT even in headless mode — conflicts require human judgment.
|
|
208
|
+
- **GATE [default: C if clean merge]** — If `{headless_mode}` and merge is clean (no [MANUAL] conflicts): auto-proceed with [C] Continue, log: "headless: clean merge, auto-continue". **Also append to in-context `headless_decisions[]`** (surfaced via `SKF_UPDATE_RESULT_JSON` by step 7): `{gate: "merge.clean-merge-gate", default_action: "C", taken_action: "C", reason: "headless: clean merge, no conflicts to resolve"}`. If conflicts exist, HALT even in headless mode — conflicts require human judgment, and the headless_decisions[] array does NOT get a continue-on-conflict entry (the workflow status becomes `halted-for-manual-mismatch` instead).
|
|
209
209
|
- ONLY proceed when user selects 'C'
|
|
210
210
|
|
|
211
211
|
**If clean merge (no conflicts):**
|
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
---
|
|
2
|
-
nextStepFile: '
|
|
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
5
|
remoteSourceResolutionData: 'references/remote-source-resolution.md'
|
|
6
6
|
tierDegradationRulesData: 'skf-create-skill/references/tier-degradation-rules.md'
|
|
7
|
+
# Resolve `{checkWorkspaceDriftHelper}` to the first existing path; HALT if
|
|
8
|
+
# neither candidate exists. §0.a relies on the helper for the deterministic
|
|
9
|
+
# workspace-pinning guard (git rev-parse + short-SHA prefix match + halt
|
|
10
|
+
# message rendering). Falling back to prose-driven git invocation would
|
|
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'
|
|
7
15
|
---
|
|
8
16
|
|
|
17
|
+
<!-- Config: communicate in {communication_language}. -->
|
|
18
|
+
|
|
9
19
|
# Step 3: Re-Extract Changed Exports
|
|
10
20
|
|
|
11
21
|
## STEP GOAL:
|
|
@@ -20,51 +30,48 @@ Perform tier-aware extraction on only the changed files identified in step 02, p
|
|
|
20
30
|
|
|
21
31
|
## MANDATORY SEQUENCE
|
|
22
32
|
|
|
23
|
-
**CRITICAL:** Follow this sequence exactly. Do not skip, reorder, or improvise unless user explicitly requests a change.
|
|
24
|
-
|
|
25
33
|
### 0. Check for Gap-Driven Mode
|
|
26
34
|
|
|
27
|
-
**If `update_mode == "gap-driven"` (set in step
|
|
35
|
+
**If `update_mode == "gap-driven"` (set in step 1 via `--from-test-report`, confirmed in step 2 section 0):**
|
|
28
36
|
|
|
29
|
-
Source code has not drifted — the gap-derived manifest from step
|
|
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.
|
|
30
38
|
|
|
31
|
-
**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
|
|
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}`:
|
|
32
40
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
```
|
|
41
|
-
Workspace HEAD does not match the commit this skill was pinned against.
|
|
41
|
+
```bash
|
|
42
|
+
uv run {checkWorkspaceDriftHelper} <source-root> \
|
|
43
|
+
--pinned-commit "<metadata.source_commit>" \
|
|
44
|
+
[--source-ref "<metadata.source_ref>"] \
|
|
45
|
+
[--allow-drift]
|
|
46
|
+
```
|
|
42
47
|
|
|
43
|
-
|
|
44
|
-
pinned ref (metadata.source_ref): {source_ref or "unset"}
|
|
45
|
-
workspace HEAD ({source_root}): {head_sha}
|
|
48
|
+
Pass `--allow-drift` only when the user provided `--allow-workspace-drift` to update-skill. The helper accepts `""` and `"local"` as the "no pinned commit" sentinels; it also auto-skips when `source_root` is not a git working tree (bare checkout, tarball extract, etc.). **For per-repo pinned-commit maps (stack skills with no single commit):** the caller must skip the helper entirely — pass nothing and log `workspace_drift_check: skipped (no pinned commit)` directly.
|
|
46
49
|
|
|
47
|
-
|
|
48
|
-
against a drifted tree silently produces wrong results (symbols appear at
|
|
49
|
-
unintended locations). Re-sync the workspace before re-running:
|
|
50
|
+
The helper emits a result envelope:
|
|
50
51
|
|
|
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
|
+
```
|
|
52
61
|
|
|
53
|
-
|
|
54
|
-
that spot-checks will read bytes that differ from the pinned commit),
|
|
55
|
-
re-run update-skill with `--allow-workspace-drift`.
|
|
56
|
-
```
|
|
62
|
+
**Dispatch on `status`:**
|
|
57
63
|
|
|
58
|
-
|
|
59
|
-
|
|
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 exit 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.
|
|
60
67
|
|
|
61
|
-
1. Use the provenance map already loaded in step
|
|
62
|
-
2. For each entry in the gap-derived change manifest from step
|
|
68
|
+
1. Use the provenance map already loaded in step 1 (at `{forge_version}/provenance-map.json`) — do not re-read
|
|
69
|
+
2. For each entry in the gap-derived change manifest from step 2:
|
|
63
70
|
- Look up the export by `name` in `provenance_map.exports` — read `source_file` and `source_line`
|
|
64
71
|
- **If export not found in provenance map:**
|
|
65
|
-
- **If the manifest entry has a `source_citation` (propagated from the test report by step
|
|
72
|
+
- **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`.
|
|
66
73
|
- **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.
|
|
67
|
-
- **If the manifest entry has no `source_citation` AND (`remediation_paths[]` is empty OR `severity` is `Medium`, `Low`, or `Info`):** 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
|
|
74
|
+
- **If the manifest entry has no `source_citation` AND (`remediation_paths[]` is empty OR `severity` is `Medium`, `Low`, or `Info`):** 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.
|
|
68
75
|
- **If export found:** read the source file at `source_line ± 5` lines and verify the symbol name still appears within that window
|
|
69
76
|
- 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 `unknown` (no usable provenance data)
|
|
70
77
|
3. Build a minimal extraction results block matching section 4's shape, with `mode: gap-driven` and per-export verification records:
|
|
@@ -100,8 +107,8 @@ Source code has not drifted — the gap-derived manifest from step-02 contains e
|
|
|
100
107
|
docstring: {summary}
|
|
101
108
|
```
|
|
102
109
|
|
|
103
|
-
4. Set `no_reextraction: true` in workflow context — step
|
|
104
|
-
5. **Skip all remaining sections of step
|
|
110
|
+
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.
|
|
111
|
+
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.
|
|
105
112
|
|
|
106
113
|
"**Gap-driven re-extraction.** Verified {verified_count}/{gap_count} citations against live source. Moved: {moved_count}. Missing: {missing_count}. Re-extracted (via remediation paths, §0a): {re_extracted_count}. Unknown (not in provenance map): {unknown_count}. Proceeding to merge."
|
|
107
114
|
|
|
@@ -113,7 +120,7 @@ Source code has not drifted — the gap-derived manifest from step-02 contains e
|
|
|
113
120
|
|
|
114
121
|
**Used by:** §0 bullet 2, when a manifest entry has no `source_citation`, has non-empty `remediation_paths[]`, and `severity` is `Critical` or `High`.
|
|
115
122
|
|
|
116
|
-
**Purpose:** produce AST-backed provenance for citation-less Critical/High gaps so step
|
|
123
|
+
**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.
|
|
117
124
|
|
|
118
125
|
**Procedure:**
|
|
119
126
|
|
|
@@ -130,7 +137,7 @@ Source code has not drifted — the gap-derived manifest from step-02 contains e
|
|
|
130
137
|
- `new_location: {file}:{start_line}` (same value — satisfies the existing consumer contract)
|
|
131
138
|
- `resolution_source: remediation-paths`
|
|
132
139
|
- `confidence: T1` (AST-extracted) or `T1-low` (pattern-matched fallback)
|
|
133
|
-
- the full extraction signature (type, params, return_type, docstring) — mirror the shape of §4's per-file extraction record so step
|
|
140
|
+
- 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.
|
|
134
141
|
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:
|
|
135
142
|
|
|
136
143
|
```
|
|
@@ -156,7 +163,7 @@ Source code has not drifted — the gap-derived manifest from step-02 contains e
|
|
|
156
163
|
|
|
157
164
|
Exit with status `halted-for-remediation-path`. Step-04 merge has not run; no partial writes.
|
|
158
165
|
|
|
159
|
-
6. **Success summary** — record `targeted_reextraction: {resolved_count, files_scanned, exports_matched, tier}` in workflow context. The evidence report (step
|
|
166
|
+
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.
|
|
160
167
|
|
|
161
168
|
**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.
|
|
162
169
|
|
|
@@ -222,7 +229,7 @@ Source code has not drifted — the gap-derived manifest from step-02 contains e
|
|
|
222
229
|
|
|
223
230
|
### 2. Extract Changed Files
|
|
224
231
|
|
|
225
|
-
**Skip authoritative doc paths.** Before iterating the change manifest, build a skip set from `promoted_docs_new[]` (populated by step
|
|
232
|
+
**Skip authoritative doc paths.** Before iterating the change manifest, build a skip set from `promoted_docs_new[]` (populated by step 2 §1b) and any existing `file_entries[]` entries with `file_type: "doc"` from the provenance map. These are documentation files tracked for drift detection only — they must not reach AST extraction, which would produce ghost entries on non-code content. If a change manifest entry matches the skip set, skip it silently and continue; doc-type drift is handled by step 2 Category D and step 4 Priority 6/7.
|
|
226
233
|
|
|
227
234
|
DO NOT BE LAZY — For EACH remaining file in the change manifest with status MODIFIED, ADDED, or RENAMED, launch a subprocess that:
|
|
228
235
|
|
|
@@ -258,7 +265,7 @@ This helps the merge step (section 4) prioritize which changes are most likely t
|
|
|
258
265
|
|
|
259
266
|
CCC failures: skip ranking silently, all changes treated equally.
|
|
260
267
|
|
|
261
|
-
**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 will return empty results and semantic ranking will be skipped. Deferred CCC indexing is implemented in create-skill step
|
|
268
|
+
**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 will return empty results and semantic ranking will be skipped. Deferred CCC indexing is implemented in create-skill step 3 but not in update-skill. All changes are treated equally for ephemeral remote sources.
|
|
262
269
|
|
|
263
270
|
**IF `tools.ccc` is false:** Skip this section silently.
|
|
264
271
|
|
|
@@ -325,12 +332,14 @@ Extraction Results:
|
|
|
325
332
|
|
|
326
333
|
### 6. Present MENU OPTIONS
|
|
327
334
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
-
|
|
331
|
-
- This is an auto-proceed step with no user choices
|
|
335
|
+
- **If `dry_run_mode` is true:** display "**Dry-run mode — skipping merge/validate/write.** Loading report..." and load `report.md` (NOT `{nextStepFile}`). The report emits the dry-run envelope describing what merge+write WOULD have done.
|
|
336
|
+
- Else, display "**Proceeding to merge...**" and after extraction results are compiled, immediately load, read entire file, then execute `{nextStepFile}`.
|
|
337
|
+
- This is an auto-proceed step with no user choices.
|
|
332
338
|
|
|
333
339
|
## CRITICAL STEP COMPLETION NOTE
|
|
334
340
|
|
|
335
|
-
ONLY WHEN all changed files have been extracted and results compiled will you load
|
|
341
|
+
ONLY WHEN all changed files have been extracted and results compiled will you load the next file:
|
|
342
|
+
|
|
343
|
+
- `dry_run_mode == true` → load `report.md`. Report emits status `dry-run`. No artifact is modified on disk by this run.
|
|
344
|
+
- Otherwise → load `{nextStepFile}` (merge.md) to begin the merge operation.
|
|
336
345
|
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: static-reference
|
|
3
|
+
---
|
|
4
|
+
|
|
1
5
|
# Remote Source Resolution (Forge/Deep Tier)
|
|
2
6
|
|
|
3
7
|
If `source_root` is a local path: proceed with the tier-appropriate strategy as normal.
|
|
@@ -83,7 +87,7 @@ After extraction is complete for all files in scope (whether successful or parti
|
|
|
83
87
|
|
|
84
88
|
## Version Reconciliation
|
|
85
89
|
|
|
86
|
-
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
|
|
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.
|
|
87
91
|
|
|
88
92
|
## AST Tool Unavailability (Local Source)
|
|
89
93
|
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
---
|
|
2
|
+
nextStepFile: 'health-check.md'
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
<!-- Config: communicate in {communication_language}. -->
|
|
6
|
+
|
|
7
|
+
# Step 7: Report
|
|
8
|
+
|
|
9
|
+
## STEP GOAL:
|
|
10
|
+
|
|
11
|
+
Present a comprehensive change summary showing what was updated, [MANUAL] sections preserved, confidence tier breakdown, and recommend next workflow actions in the SKF chain.
|
|
12
|
+
|
|
13
|
+
## Rules
|
|
14
|
+
|
|
15
|
+
- Focus only on reporting — all operations are complete; do not modify any files
|
|
16
|
+
- Present clear, actionable summary with next step recommendations
|
|
17
|
+
- Chains to the local health-check step via `{nextStepFile}` after completion — the user-facing summary is NOT the terminal step
|
|
18
|
+
|
|
19
|
+
## MANDATORY SEQUENCE
|
|
20
|
+
|
|
21
|
+
### 1. Handle No-Change Shortcut
|
|
22
|
+
|
|
23
|
+
**If routed here from step 02 with no changes detected:**
|
|
24
|
+
|
|
25
|
+
"**Update Skill Report: {skill_name}**
|
|
26
|
+
|
|
27
|
+
**Status:** No changes detected
|
|
28
|
+
|
|
29
|
+
Source code matches provenance map exactly. The skill `{skill_name}` is current — no update was needed.
|
|
30
|
+
|
|
31
|
+
**Provenance age:** {days} days since last extraction
|
|
32
|
+
**Forge tier:** {tier}
|
|
33
|
+
|
|
34
|
+
**Recommendation:** No action required. Run audit-skill periodically to monitor for drift."
|
|
35
|
+
|
|
36
|
+
→ Load, read the full file, and execute `{nextStepFile}` — the health-check step is the true terminal step of this workflow.
|
|
37
|
+
|
|
38
|
+
### 1a. Handle Detect-Only Mode
|
|
39
|
+
|
|
40
|
+
**If `detect_only_mode` is true (routed here from detect-changes.md §6):**
|
|
41
|
+
|
|
42
|
+
"**Update Skill Report: {skill_name} — Detect-Only Mode**
|
|
43
|
+
|
|
44
|
+
**Status:** Detect-only (no writes)
|
|
45
|
+
|
|
46
|
+
The change manifest below describes what would be updated. No artifact was modified — re-run without `--detect-only` to apply.
|
|
47
|
+
|
|
48
|
+
{render the change manifest summary table from detect-changes.md §5, plus the per-file detail section}
|
|
49
|
+
|
|
50
|
+
**Recommendation:** Review the manifest; if it matches expectations, re-run `skf-update-skill` without `--detect-only` to perform the actual update."
|
|
51
|
+
|
|
52
|
+
The headless envelope (`SKF_UPDATE_RESULT_JSON`) carries `status: "detect-only"`, `files_written: []`, and any `headless_decisions[]` recorded by detect-changes' §1b / §1c / §2.2 gates. `version` and `previous_version` are both equal to the on-disk version (detect-only does not bump). `update_mode` reflects the run's mode (`normal` or `gap-driven` or `degraded`) so consumers know which detection path produced the manifest.
|
|
53
|
+
|
|
54
|
+
→ Load, read the full file, and execute `{nextStepFile}` (health-check) — even detect-only runs through the terminal health-check step.
|
|
55
|
+
|
|
56
|
+
### 1b. Handle Dry-Run Mode
|
|
57
|
+
|
|
58
|
+
**If `dry_run_mode` is true (routed here from re-extract.md §6):**
|
|
59
|
+
|
|
60
|
+
"**Update Skill Report: {skill_name} — Dry-Run Mode**
|
|
61
|
+
|
|
62
|
+
**Status:** Dry-run (no writes)
|
|
63
|
+
|
|
64
|
+
The change manifest below shows what was detected; re-extraction ran to compute the planned merge but neither merge nor write executed. No artifact was modified.
|
|
65
|
+
|
|
66
|
+
{render the change manifest summary AND the re-extraction summary — what merge+validate+write WOULD have done}
|
|
67
|
+
|
|
68
|
+
**Planned writes (skipped):**
|
|
69
|
+
- SKILL.md re-merge with re-extracted exports
|
|
70
|
+
- metadata.json version bump (or hold for gap-driven)
|
|
71
|
+
- provenance-map.json update with re-extraction results
|
|
72
|
+
- evidence-report.md
|
|
73
|
+
- context-snippet.md (only if a staleness trigger fired)
|
|
74
|
+
- active-symlink flip (only if version changed)
|
|
75
|
+
|
|
76
|
+
**Recommendation:** Review the manifest and re-extraction summary; if both match expectations, re-run `skf-update-skill` without `--dry-run` to perform the actual update."
|
|
77
|
+
|
|
78
|
+
The headless envelope carries `status: "dry-run"`, `files_written: []`, the `headless_decisions[]` recorded so far (everything before merge), and `update_mode` from the run.
|
|
79
|
+
|
|
80
|
+
→ Load, read the full file, and execute `{nextStepFile}` (health-check).
|
|
81
|
+
|
|
82
|
+
### 2. Present Change Summary
|
|
83
|
+
|
|
84
|
+
"**Update Skill Report: {skill_name}**
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
### Operation Summary
|
|
89
|
+
|
|
90
|
+
| Metric | Value |
|
|
91
|
+
|--------|-------|
|
|
92
|
+
| **Skill** | {skill_name} ({single/stack}) |
|
|
93
|
+
| **Forge Tier** | {tier} |
|
|
94
|
+
| **Mode** | {update_mode}{mode_fallback_note} |
|
|
95
|
+
| **Duration** | {step count} steps |
|
|
96
|
+
|
|
97
|
+
**`{update_mode}`** is one of `normal`, `gap-driven`, or `degraded` (mirrors the `update_mode` field of `SKF_UPDATE_RESULT_JSON`).
|
|
98
|
+
|
|
99
|
+
**`{mode_fallback_note}`** surfaces weak-signal fallbacks the workflow took silently and would otherwise be buried in the evidence report. Render it inline after the mode value when any of these conditions fire; render the empty string when none did:
|
|
100
|
+
|
|
101
|
+
- `--from-test-report` was passed but the test report was missing at the expected path, so step 1 fell back to `normal` mode → ` (gap-driven requested; test report missing — fell back to normal)`
|
|
102
|
+
- `re-extract.md §0.a` skipped the workspace-drift guard because `source_root` is not a git working tree (or HEAD was unreadable) → ` (workspace-drift check skipped: {skip_reason})` where `{skip_reason}` is the helper's `skip_reason` field (`not-a-git-tree` or `HEAD unreadable`)
|
|
103
|
+
- Both fallbacks fired: concatenate both parenthetical notes with `; ` between them
|
|
104
|
+
|
|
105
|
+
These signals also appear in `warnings[]` on the headless envelope; the Mode row makes them visible to interactive users who scan the report without parsing the envelope.
|
|
106
|
+
|
|
107
|
+
### Changes Applied
|
|
108
|
+
|
|
109
|
+
| Category | Count |
|
|
110
|
+
|----------|-------|
|
|
111
|
+
| Files modified | {count} |
|
|
112
|
+
| Files added | {count} |
|
|
113
|
+
| Files deleted | {count} |
|
|
114
|
+
| Files moved/renamed | {count} |
|
|
115
|
+
| **Total exports affected** | {count} |
|
|
116
|
+
|
|
117
|
+
### Export Changes
|
|
118
|
+
|
|
119
|
+
| Change Type | Count |
|
|
120
|
+
|-------------|-------|
|
|
121
|
+
| Updated (signature/type change) | {count} |
|
|
122
|
+
| Added (new exports) | {count} |
|
|
123
|
+
| Removed (deleted exports) | {count} |
|
|
124
|
+
| Moved (file relocated) | {count} |
|
|
125
|
+
| Renamed (identifier changed) | {count} |
|
|
126
|
+
|
|
127
|
+
### Confidence Tier Breakdown
|
|
128
|
+
|
|
129
|
+
| Tier | Count | Description |
|
|
130
|
+
|------|-------|-------------|
|
|
131
|
+
| T1 | {count} | AST-verified structural extraction |
|
|
132
|
+
| T1-low | {count} | Pattern-matched (Quick tier or degraded) |
|
|
133
|
+
| T2 | {count} | QMD-enriched semantic context |
|
|
134
|
+
|
|
135
|
+
### [MANUAL] Section Preservation
|
|
136
|
+
|
|
137
|
+
| Metric | Count |
|
|
138
|
+
|--------|-------|
|
|
139
|
+
| Sections preserved | {count} |
|
|
140
|
+
| Conflicts resolved | {count} |
|
|
141
|
+
| Orphans kept | {count} |
|
|
142
|
+
| Orphans removed | {count} |
|
|
143
|
+
| **Integrity** | {VERIFIED / count issues} |"
|
|
144
|
+
|
|
145
|
+
### 3. Present Validation Findings (If Any)
|
|
146
|
+
|
|
147
|
+
**If validation findings exist from step 05:**
|
|
148
|
+
|
|
149
|
+
"### Validation Findings
|
|
150
|
+
|
|
151
|
+
| Check | Status | Issues |
|
|
152
|
+
|-------|--------|--------|
|
|
153
|
+
| Spec compliance | {PASS/WARN/FAIL} | {count} |
|
|
154
|
+
| [MANUAL] integrity | {PASS/WARN/FAIL} | {count} |
|
|
155
|
+
| Confidence tiers | {PASS/WARN/FAIL} | {count} |
|
|
156
|
+
| Provenance | {PASS/WARN/FAIL} | {count} |
|
|
157
|
+
|
|
158
|
+
{List specific findings if WARN or FAIL}"
|
|
159
|
+
|
|
160
|
+
**If all validations passed:** "### Validation: All checks passed."
|
|
161
|
+
|
|
162
|
+
### 4. Show Files Updated
|
|
163
|
+
|
|
164
|
+
"### Files Written
|
|
165
|
+
|
|
166
|
+
| File | Status |
|
|
167
|
+
|------|--------|
|
|
168
|
+
| `{resolved_skill_package}/SKILL.md` | Updated |
|
|
169
|
+
| `{resolved_skill_package}/metadata.json` | Updated |
|
|
170
|
+
| `{forge_version}/provenance-map.json` | Updated |
|
|
171
|
+
| `{forge_version}/evidence-report.md` | Appended |
|
|
172
|
+
| {stack reference files if applicable} | Updated |
|
|
173
|
+
|
|
174
|
+
Where `{resolved_skill_package}` = `{skills_output_folder}/{skill_name}/{version}/{skill_name}/` and `{forge_version}` = `{forge_data_folder}/{skill_name}/{version}/` — see `knowledge/version-paths.md`."
|
|
175
|
+
|
|
176
|
+
### 5. Workflow Chaining Recommendations
|
|
177
|
+
|
|
178
|
+
"### Next Steps
|
|
179
|
+
|
|
180
|
+
Based on the update results:"
|
|
181
|
+
|
|
182
|
+
**If all validations passed:**
|
|
183
|
+
"- **audit-skill** — Run to verify the update resolved known drift
|
|
184
|
+
- **export-skill** — Package the updated skill for distribution
|
|
185
|
+
- **test-skill** — Run test suite against the updated skill"
|
|
186
|
+
|
|
187
|
+
**If validation warnings/failures exist:**
|
|
188
|
+
"- **audit-skill** — Run to identify remaining issues
|
|
189
|
+
- Review validation findings above before exporting"
|
|
190
|
+
|
|
191
|
+
**If triggered by audit-skill chain:**
|
|
192
|
+
"- **audit-skill** — Re-run to verify CRITICAL/HIGH drift resolved
|
|
193
|
+
- **export-skill** — Package once audit confirms clean state"
|
|
194
|
+
|
|
195
|
+
### 5b. Result Contract
|
|
196
|
+
|
|
197
|
+
Write the result contract per `shared/references/output-contract-schema.md`: the per-run record at `{forge_version}/update-skill-result-{YYYYMMDD-HHmmss}.json` (UTC timestamp, resolution to seconds) and a copy at `{forge_version}/update-skill-result-latest.json` (stable path for pipeline consumers — copy, not symlink). Include all modified file paths in `outputs`; include `exports_affected`, `files_modified`, and `validation_status` (passed/warnings/failures) in `summary`.
|
|
198
|
+
|
|
199
|
+
**Headless envelope (`SKF_UPDATE_RESULT_JSON`):** when `{headless_mode}` is true, ALSO emit a single-line JSON envelope to stdout prefixed with the literal `SKF_UPDATE_RESULT_JSON: `. Schema: `src/shared/scripts/schemas/skf-update-result-envelope.v1.json`. Construct the envelope from in-context state:
|
|
200
|
+
|
|
201
|
+
```json
|
|
202
|
+
SKF_UPDATE_RESULT_JSON: {"skf_update":{"status":"success|no-changes|halted-for-*|blocked","skill_name":"<name>","version":"<v>","previous_version":"<v>","update_mode":"normal|gap-driven|degraded","files_written":[...],"headless_decisions":[...],"warnings":[...],"error":null|{...}}}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
- `headless_decisions[]` — verbatim from the in-context array populated by gates (init.md §confirmation, detect-changes.md §1b/§1c/§2.2, merge.md §gate). Each entry `{gate, default_action, taken_action, reason, evidence?}`. Empty when no gates auto-resolved (e.g. no-changes path skipped detect-changes' gates).
|
|
206
|
+
- `status` — single-field outcome for pipeline branching. `"success"` when the run wrote artifacts and produced no halts; `"no-changes"` when §1 short-circuited; one of the documented `halted-for-*` codes when a halt fired; `"blocked"` as the catch-all.
|
|
207
|
+
- `error` — null on success or no-changes. Object `{phase, path?, reason}` describing the failure when a halt or write error fired. Pipelines branch on `error !== null` for non-zero exit semantics.
|
|
208
|
+
|
|
209
|
+
The headless envelope is the structured channel; the per-run JSON written above is the audit trail. Both coexist — the envelope is one line on stdout for grep-friendly consumption, the per-run JSON is the full record on disk.
|
|
210
|
+
|
|
211
|
+
### 6. Chain to Health Check
|
|
212
|
+
|
|
213
|
+
ONLY WHEN the change summary has been presented, files-written list displayed, and result contract saved will you then load, read the full file, and execute `{nextStepFile}`. The health-check step is the true terminal step — do not stop here even though the report reads as final.
|
|
214
|
+
|