bmad-module-skill-forge 1.4.1 → 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 +34 -4
- 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/{steps-c/step-01-init.md → references/init.md} +57 -19
- 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 -17
- 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} +11 -11
- 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} +11 -11
- 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} +11 -49
- 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} +20 -8
- 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} +109 -113
- 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} +16 -31
- 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-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
package/src/skf-analyze-source/{steps-c/step-02-scan-project.md → references/scan-project.md}
RENAMED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
---
|
|
2
|
-
nextStepFile: '
|
|
2
|
+
nextStepFile: 'identify-units.md'
|
|
3
3
|
outputFile: '{forge_data_folder}/analyze-source-report-{project_name}.md'
|
|
4
4
|
heuristicsFile: 'references/unit-detection-heuristics.md'
|
|
5
|
+
scanManifestsScript: '{project-root}/src/shared/scripts/skf-scan-manifests.py'
|
|
5
6
|
---
|
|
6
7
|
|
|
8
|
+
<!-- Config: communicate in {communication_language}. -->
|
|
9
|
+
|
|
7
10
|
# Step 2: Scan Project
|
|
8
11
|
|
|
9
12
|
## STEP GOAL:
|
|
@@ -14,13 +17,11 @@ To map the complete project structure by scanning directory trees, detecting ser
|
|
|
14
17
|
|
|
15
18
|
- Focus only on structural scanning — do not classify units or map exports yet
|
|
16
19
|
- Do not read source file contents beyond manifest files and entry points
|
|
17
|
-
-
|
|
20
|
+
- Delegate per-file scanning to subagents in parallel when many files are involved (main-thread fallback is fine)
|
|
18
21
|
- Tier-aware scanning depth: Quick (file structure), Forge (+ manifest parsing), Deep (+ config analysis)
|
|
19
22
|
|
|
20
23
|
## MANDATORY SEQUENCE
|
|
21
24
|
|
|
22
|
-
**CRITICAL:** Follow this sequence exactly. Do not skip, reorder, or improvise unless user explicitly requests a change.
|
|
23
|
-
|
|
24
25
|
### 1. Load Context
|
|
25
26
|
|
|
26
27
|
Read {outputFile} frontmatter to obtain:
|
|
@@ -36,9 +37,9 @@ Load {heuristicsFile} for reference on detection signals.
|
|
|
36
37
|
|
|
37
38
|
1. Map the top-level directory tree (2-3 levels deep)
|
|
38
39
|
2. Identify workspace configuration files (pnpm-workspace.yaml, lerna.json, Cargo.toml [workspace], go.work, etc.)
|
|
39
|
-
3.
|
|
40
|
+
3. Enumerate package manifests deterministically — invoke `uv run {scanManifestsScript} scan {path}` and parse the JSON envelope. The script returns `{manifests[], total_unique, monorepo, warnings?}` covering npm/python/rust/go/maven/gradle/ruby/composer/swift; record each `{path, ecosystem}` for the manifests catalog in §4 and capture `monorepo` for the boundary-signal pass in §3
|
|
40
41
|
4. Locate entry point files (index.ts, main.ts, app.ts, main.go, main.rs, __init__.py, etc.)
|
|
41
|
-
5. Detect service configuration (Dockerfile, docker-compose.yml, kubernetes manifests, serverless.yml)
|
|
42
|
+
5. Detect service configuration (Dockerfile, docker-compose.yml, kubernetes manifests, serverless.yml) — keep this step LLM-driven; file glob + presence check is sufficient, no parsing required
|
|
42
43
|
6. Return structured findings — file paths and types only, not contents
|
|
43
44
|
|
|
44
45
|
**If subprocess unavailable:** Perform directory scanning in main thread using file I/O tools.
|
|
@@ -120,7 +121,7 @@ Wait for user feedback. If user identifies gaps, rescan as directed.
|
|
|
120
121
|
|
|
121
122
|
Append the complete "## Project Scan" section to {outputFile}:
|
|
122
123
|
|
|
123
|
-
Replace the placeholder `[Appended by
|
|
124
|
+
Replace the placeholder `[Appended by scan-project]` with the full scan results including:
|
|
124
125
|
- Structure overview
|
|
125
126
|
- Detected boundaries table
|
|
126
127
|
- Manifests catalog
|
|
@@ -130,17 +131,18 @@ Replace the placeholder `[Appended by step-02-scan-project]` with the full scan
|
|
|
130
131
|
|
|
131
132
|
Update {outputFile} frontmatter:
|
|
132
133
|
```yaml
|
|
133
|
-
stepsCompleted: [append '
|
|
134
|
-
lastStep: '
|
|
134
|
+
stepsCompleted: [append 'scan-project' to existing array]
|
|
135
|
+
lastStep: 'scan-project'
|
|
135
136
|
```
|
|
136
137
|
|
|
137
138
|
### 7. Present MENU OPTIONS
|
|
138
139
|
|
|
139
|
-
Display: "**Select:** [C] Continue to Unit Identification"
|
|
140
|
+
Display: "**Select:** [C] Continue to Unit Identification | [X] Cancel and exit"
|
|
140
141
|
|
|
141
142
|
#### Menu Handling Logic:
|
|
142
143
|
|
|
143
144
|
- IF C: Save scan results to {outputFile}, update frontmatter, then load, read entire file, then execute {nextStepFile}
|
|
145
|
+
- IF X: HARD HALT with exit code 6 (`user-cancelled`). Emit the `SKF_ANALYZE_RESULT_JSON` envelope on stderr with `status: "error"`, `halt_reason: "user-cancelled"`, and counts/paths reflecting state at cancellation
|
|
144
146
|
- IF Any other: help user, then [Redisplay Menu Options](#7-present-menu-options)
|
|
145
147
|
|
|
146
148
|
#### EXECUTION RULES:
|
|
@@ -18,24 +18,24 @@ nextWorkflow: ''
|
|
|
18
18
|
|
|
19
19
|
## Project Scan
|
|
20
20
|
|
|
21
|
-
[Appended by
|
|
21
|
+
[Appended by scan-project]
|
|
22
22
|
|
|
23
23
|
## Identified Units
|
|
24
24
|
|
|
25
|
-
[Appended by
|
|
25
|
+
[Appended by identify-units]
|
|
26
26
|
|
|
27
27
|
## Export Map
|
|
28
28
|
|
|
29
|
-
[Appended by
|
|
29
|
+
[Appended by map-and-detect]
|
|
30
30
|
|
|
31
31
|
## Integration Points
|
|
32
32
|
|
|
33
|
-
[Appended by
|
|
33
|
+
[Appended by map-and-detect]
|
|
34
34
|
|
|
35
35
|
## Recommendations
|
|
36
36
|
|
|
37
|
-
[Appended by
|
|
37
|
+
[Appended by recommend]
|
|
38
38
|
|
|
39
39
|
## Generation Results
|
|
40
40
|
|
|
41
|
-
[Appended by
|
|
41
|
+
[Appended by generate-briefs]
|
|
@@ -9,6 +9,14 @@ description: Drift detection between skill and current source code. Use when the
|
|
|
9
9
|
|
|
10
10
|
Detects drift between an existing skill and its current source code, producing a severity-graded drift report with AST-backed findings and actionable remediation suggestions. Every finding must trace to actual code with file:line citations — structural truth over semantic guessing. Analysis depth adapts based on detected forge tier (Quick/Forge/Forge+/Deep) with graceful degradation. Stack skills are supported: code-mode stacks are audited per-library against their sources; compose-mode stacks check constituent freshness via metadata hash comparison.
|
|
11
11
|
|
|
12
|
+
## Conventions
|
|
13
|
+
|
|
14
|
+
- Bare paths (e.g. `references/<name>.md`) resolve from the skill root.
|
|
15
|
+
- `references/` holds prompt content carved out of SKILL.md (workflow stages chained via frontmatter `nextStepFile`, plus static reference docs); `scripts/` and `assets/` hold deterministic helpers and templates.
|
|
16
|
+
- `{skill-root}` resolves to this skill's installed directory (where `customize.toml` lives, if present).
|
|
17
|
+
- `{project-root}`-prefixed paths resolve from the project working directory.
|
|
18
|
+
- `{skill-name}` resolves to the skill directory's basename.
|
|
19
|
+
|
|
12
20
|
## Role
|
|
13
21
|
|
|
14
22
|
You are a skill auditor operating in Ferris Audit mode. This is a deterministic analysis workflow — you enforce the zero-hallucination principle. You bring AST analysis expertise and drift detection methodology, while the source code provides the ground truth.
|
|
@@ -18,11 +26,8 @@ You are a skill auditor operating in Ferris Audit mode. This is a deterministic
|
|
|
18
26
|
These rules apply to every step in this workflow:
|
|
19
27
|
|
|
20
28
|
- Never fabricate findings — all data must trace to source code with file:line citations
|
|
21
|
-
- Read each step file completely before taking any action
|
|
22
|
-
- Follow the mandatory sequence in each step exactly — do not skip, reorder, or optimize
|
|
23
29
|
- Only load one step file at a time — never preload future steps
|
|
24
30
|
- Update `stepsCompleted` in output file frontmatter before loading next step
|
|
25
|
-
- If any instruction references a subprocess or tool you lack, achieve the outcome in your main context thread
|
|
26
31
|
- Always communicate in `{communication_language}`
|
|
27
32
|
- If `{headless_mode}` is true, auto-proceed through confirmation gates with their default action and log each auto-decision
|
|
28
33
|
|
|
@@ -30,22 +35,45 @@ These rules apply to every step in this workflow:
|
|
|
30
35
|
|
|
31
36
|
| # | Step | File | Auto-proceed |
|
|
32
37
|
|---|------|------|--------------|
|
|
33
|
-
| 1 | Initialize & Baseline |
|
|
34
|
-
| 2 | Re-Index Source |
|
|
35
|
-
| 3 | Structural Diff |
|
|
36
|
-
| 4 | Semantic Diff |
|
|
37
|
-
| 5 | Severity Classification |
|
|
38
|
-
| 6 | Report |
|
|
39
|
-
| 7 | Workflow Health Check |
|
|
38
|
+
| 1 | Initialize & Baseline | references/init.md | No (confirm) |
|
|
39
|
+
| 2 | Re-Index Source | references/re-index.md | Yes |
|
|
40
|
+
| 3 | Structural Diff | references/structural-diff.md | Yes |
|
|
41
|
+
| 4 | Semantic Diff | references/semantic-diff.md | Yes (skip at non-Deep) |
|
|
42
|
+
| 5 | Severity Classification | references/severity-classify.md | Yes |
|
|
43
|
+
| 6 | Report | references/report.md | Yes |
|
|
44
|
+
| 7 | Workflow Health Check | references/health-check.md | Yes |
|
|
40
45
|
|
|
41
46
|
## Invocation Contract
|
|
42
47
|
|
|
43
48
|
| Aspect | Detail |
|
|
44
49
|
|--------|--------|
|
|
45
|
-
| **Inputs** | skill_name [required] |
|
|
46
|
-
| **Gates** | step
|
|
47
|
-
| **Outputs** | drift-report-{timestamp}.md with drift_score and nextWorkflow |
|
|
48
|
-
| **Headless** | All gates auto-resolve with default action when `{headless_mode}` is true |
|
|
50
|
+
| **Inputs** | `skill_name` [required], `skill_path` [optional override — full path to skill directory; bypasses manifest/symlink resolution], `tier_override` [optional: Quick / Forge / Forge+ / Deep — overrides detected tier], `degraded` [optional bool — pre-confirm degraded-mode opt-in when no provenance map exists], `upstream_drift_choice` [optional: C / S / X — pre-supplied answer for the upstream-drift gate at init.md §5b], `dirty_worktree_choice` [optional: T / A / F — pre-supplied answer for the dirty-worktree sub-gate at init.md §5b], `force` [optional bool — when paired with `dirty_worktree_choice=F` or used for any future destructive-action gate, signals consent to skip the confirmation] |
|
|
51
|
+
| **Gates** | step 1: Manifest-vs-Symlink Gate [N] · Upstream-Drift Gate [C/S/X] · Dirty-Worktree Sub-Gate [T/A/F] · Degraded-Mode Gate [D/X] · Baseline Confirm Gate [C] |
|
|
52
|
+
| **Outputs** | `drift-report-{timestamp}.md` at `{forge_version}/` with `drift_score` and `nextWorkflow` frontmatter; per-run result contract at `{forge_version}/audit-skill-result-{timestamp}.json` plus `-latest.json` copy; final `SKF_AUDIT_RESULT_JSON` line on stdout when `{headless_mode}` is true |
|
|
53
|
+
| **Headless** | All gates auto-resolve with default action when `{headless_mode}` is true; pre-supplied inputs (`upstream_drift_choice`, `dirty_worktree_choice`, `degraded`, `tier_override`) consumed at the gates that would otherwise prompt |
|
|
54
|
+
| **Exit codes** | See "Exit Codes" below |
|
|
55
|
+
|
|
56
|
+
## Exit Codes
|
|
57
|
+
|
|
58
|
+
Every HARD HALT in this workflow exits with a stable code so headless automators can branch on the failure class without grepping message text:
|
|
59
|
+
|
|
60
|
+
| Code | Meaning | Raised by |
|
|
61
|
+
| ---- | -------------------- | ------------------------------------------------------------------------------------------------------------------ |
|
|
62
|
+
| 0 | success | step 7 (terminal health-check) |
|
|
63
|
+
| 2 | input-missing | step 1 §1 — no `skill_name` supplied in headless mode (interactive prompt cannot resolve) |
|
|
64
|
+
| 3 | resolution-failure | step 1 §1 (skill not found at resolved path: missing `SKILL.md`); step 1 §2 (`forge-tier.yaml` missing — setup-forge not run); step 1 §5 (source directory from provenance map no longer exists / inaccessible) |
|
|
65
|
+
| 4 | write-failure | step 1 §6 / step 6 §3 (drift report write failed: read-only mount, disk full, permissions denied) |
|
|
66
|
+
| 6 | user-cancelled | step 1 §1 manifest-vs-symlink gate `[X]` · step 1 §4 degraded-mode gate `[X]` · step 1 §5b upstream-drift gate `[X]` · step 1 §5b dirty-worktree sub-gate `[A]` (and `[A]` headless default) |
|
|
67
|
+
|
|
68
|
+
## Result Contract (Headless)
|
|
69
|
+
|
|
70
|
+
When `{headless_mode}` is true, step 6 emits a single-line JSON envelope on **stdout** before chaining to step 7, and every HARD HALT emits the same envelope shape on **stderr** with `status: "error"`:
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
SKF_AUDIT_RESULT_JSON: {"status":"success|error","skill_name":"…","drift_score":"CLEAN|MINOR|SIGNIFICANT|CRITICAL|null","report_path":"…|null","next_workflow":"update-skill|null","audit_ref":"…|null","exit_code":0,"halt_reason":null}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
`status` is `"success"` on the terminal happy path, `"error"` on any HALT. `drift_score` is `null` when the workflow halted before severity classification ran. `next_workflow` is `"update-skill"` when CRITICAL or HIGH findings exist, otherwise `null`. `halt_reason` is one of: `null` (success), `"input-missing"`, `"skill-not-found"`, `"forge-tier-missing"`, `"source-dir-missing"`, `"write-failed"`, `"user-cancelled"`. `exit_code` matches the table above.
|
|
49
77
|
|
|
50
78
|
## On Activation
|
|
51
79
|
|
|
@@ -56,4 +84,27 @@ These rules apply to every step in this workflow:
|
|
|
56
84
|
|
|
57
85
|
2. **Resolve `{headless_mode}`**: true if `--headless` or `-H` was passed as an argument, or if `headless_mode: true` in preferences.yaml. Default: false.
|
|
58
86
|
|
|
59
|
-
3.
|
|
87
|
+
3. **Resolve workflow customization.** Run:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
python3 {project-root}/_bmad/scripts/resolve_customization.py \
|
|
91
|
+
--skill {skill-root} --key workflow
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
The script merges the three customization layers per `bmad-customize`'s structural merge rules (scalars override, arrays append):
|
|
95
|
+
|
|
96
|
+
- `{skill-root}/customize.toml` — bundled defaults
|
|
97
|
+
- `_bmad/custom/<skill-name>.toml` under `{project-root}` — team overrides (committed)
|
|
98
|
+
- `_bmad/custom/<skill-name>.user.toml` under `{project-root}` — personal overrides (gitignored)
|
|
99
|
+
|
|
100
|
+
If the script fails or is missing, fall back to reading `{skill-root}/customize.toml` directly — the bundled defaults are an empty string for each path scalar.
|
|
101
|
+
|
|
102
|
+
Apply the path-scalar fallback now so stage files don't have to repeat the conditional logic. For each of the scalars, if the merged value is empty or absent, use the bundled default:
|
|
103
|
+
|
|
104
|
+
- `{driftReportTemplatePath}` ← `workflow.drift_report_template_path` if non-empty, else `assets/drift-report-template.md`
|
|
105
|
+
- `{severityRulesPath}` ← `workflow.severity_rules_path` if non-empty, else `references/severity-rules.md`
|
|
106
|
+
- `{onCompleteCommand}` ← `workflow.on_complete` if non-empty, else empty (no-op — report.md skips the hook invocation entirely)
|
|
107
|
+
|
|
108
|
+
Stash all three as workflow-context variables. Stage files reference `{driftReportTemplatePath}` / `{severityRulesPath}` / `{onCompleteCommand}` directly — no conditional at the usage site. Empty-string overrides cleanly fall through to the bundled default; non-empty values let orgs swap in house-style copies (custom drift-report layout, stricter severity thresholds) or wire in post-audit hooks (Slack notifier, ticket-tracker integration) without forking the skill.
|
|
109
|
+
|
|
110
|
+
4. Load, read the full file, and then execute `references/init.md` to begin the workflow.
|
|
@@ -17,6 +17,7 @@ previousWorkflow: 'create-skill'
|
|
|
17
17
|
|
|
18
18
|
## Audit Summary
|
|
19
19
|
|
|
20
|
+
**Confidence Mode:** {confidence_mode}
|
|
20
21
|
**Skill:** {skill_name}
|
|
21
22
|
**Source:** {source_path}
|
|
22
23
|
**Tier:** {forge_tier}
|
|
@@ -35,28 +36,28 @@ previousWorkflow: 'create-skill'
|
|
|
35
36
|
|
|
36
37
|
## Structural Drift
|
|
37
38
|
|
|
38
|
-
<!-- Appended by
|
|
39
|
+
<!-- Appended by structural-diff -->
|
|
39
40
|
|
|
40
41
|
---
|
|
41
42
|
|
|
42
43
|
## Semantic Drift
|
|
43
44
|
|
|
44
|
-
<!-- Appended by
|
|
45
|
+
<!-- Appended by semantic-diff (Deep tier only) -->
|
|
45
46
|
|
|
46
47
|
---
|
|
47
48
|
|
|
48
49
|
## Severity Classification
|
|
49
50
|
|
|
50
|
-
<!-- Appended by
|
|
51
|
+
<!-- Appended by severity-classify -->
|
|
51
52
|
|
|
52
53
|
---
|
|
53
54
|
|
|
54
55
|
## Remediation Suggestions
|
|
55
56
|
|
|
56
|
-
<!-- Appended by
|
|
57
|
+
<!-- Appended by report -->
|
|
57
58
|
|
|
58
59
|
---
|
|
59
60
|
|
|
60
61
|
## Provenance
|
|
61
62
|
|
|
62
|
-
<!-- Appended by
|
|
63
|
+
<!-- Appended by report -->
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# DO NOT EDIT -- overwritten on every update.
|
|
2
|
+
#
|
|
3
|
+
# Workflow customization surface for skf-audit-skill.
|
|
4
|
+
|
|
5
|
+
[workflow]
|
|
6
|
+
|
|
7
|
+
# --- Configurable below. Overrides merge per BMad structural rules: ---
|
|
8
|
+
# scalars: override wins • arrays (persistent_facts, activation_steps_*): append
|
|
9
|
+
# arrays-of-tables with `code`/`id`: replace matching items, append new ones.
|
|
10
|
+
|
|
11
|
+
# Steps to run before the standard activation (uv probe, config load).
|
|
12
|
+
# Overrides append. Use for org-wide pre-flight checks (auth, network,
|
|
13
|
+
# compliance) that must precede any audit work.
|
|
14
|
+
|
|
15
|
+
activation_steps_prepend = []
|
|
16
|
+
|
|
17
|
+
# Steps to run after activation but before the first stage executes.
|
|
18
|
+
# Overrides append. Use for context loads or banner customization that
|
|
19
|
+
# should run once activation completes successfully.
|
|
20
|
+
|
|
21
|
+
activation_steps_append = []
|
|
22
|
+
|
|
23
|
+
# Persistent facts the workflow keeps in mind for the whole run
|
|
24
|
+
# (house style, severity-threshold policies, audit guardrails).
|
|
25
|
+
# Overrides append.
|
|
26
|
+
#
|
|
27
|
+
# Each entry is either:
|
|
28
|
+
# - a literal sentence, e.g. "Critical drift requires CODEOWNERS notification."
|
|
29
|
+
# - a file reference prefixed with `file:`, e.g.
|
|
30
|
+
# "file:{project-root}/docs/audit-policy.md" (globs supported; file
|
|
31
|
+
# contents are loaded and treated as facts).
|
|
32
|
+
|
|
33
|
+
persistent_facts = [
|
|
34
|
+
"file:{project-root}/**/project-context.md",
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
# --- Optional asset overrides ---
|
|
38
|
+
#
|
|
39
|
+
# Lift the canonical asset paths so orgs can substitute house-style copies
|
|
40
|
+
# without forking the skill. Empty string = use the bundled default.
|
|
41
|
+
|
|
42
|
+
drift_report_template_path = ""
|
|
43
|
+
severity_rules_path = ""
|
|
44
|
+
|
|
45
|
+
# Optional post-audit hook. When non-empty, invoked with
|
|
46
|
+
# `--result-path=<path>` after the drift report and result JSON are finalized.
|
|
47
|
+
# Failures are logged to workflow_warnings[] but never fail the workflow.
|
|
48
|
+
|
|
49
|
+
on_complete = ""
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
# `shared/health-check.md` resolves relative to the SKF module root
|
|
3
|
-
# (`_bmad/skf/` when installed, `src/` during
|
|
4
|
-
# to this step file.
|
|
3
|
+
# (`{project-root}/_bmad/skf/` when installed, `{project-root}/src/` during
|
|
4
|
+
# development), NOT relative to this step file.
|
|
5
5
|
nextStepFile: 'shared/health-check.md'
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
+
<!-- Config: communicate in {communication_language}. -->
|
|
9
|
+
|
|
8
10
|
# Step 7: Workflow Health Check
|
|
9
11
|
|
|
10
12
|
## STEP GOAL:
|
|
@@ -13,7 +15,7 @@ Chain to the shared workflow self-improvement health check at `{nextStepFile}`.
|
|
|
13
15
|
|
|
14
16
|
## Rules
|
|
15
17
|
|
|
16
|
-
- No user-facing reports, file writes, or result contracts in this step — those belong in step
|
|
18
|
+
- No user-facing reports, file writes, or result contracts in this step — those belong in step 6
|
|
17
19
|
- Delegate directly to `{nextStepFile}` with no additional commentary
|
|
18
20
|
- Do not attempt any other action between loading this step and executing `{nextStepFile}`
|
|
19
21
|
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
---
|
|
2
|
-
nextStepFile: '
|
|
2
|
+
nextStepFile: 're-index.md'
|
|
3
3
|
outputFile: '{forge_version}/drift-report-{timestamp}.md'
|
|
4
4
|
templateFile: 'assets/drift-report-template.md'
|
|
5
|
+
loadProvenanceScript: '{project-root}/src/shared/scripts/skf-load-provenance.py'
|
|
6
|
+
compareFileHashesScript: '{project-root}/src/shared/scripts/skf-compare-file-hashes.py'
|
|
5
7
|
---
|
|
6
8
|
|
|
9
|
+
<!-- Config: communicate in {communication_language}. -->
|
|
10
|
+
|
|
7
11
|
# Step 1: Initialize Audit
|
|
8
12
|
|
|
9
13
|
## STEP GOAL:
|
|
@@ -19,7 +23,7 @@ Load the existing skill artifacts, provenance map, and forge tier configuration
|
|
|
19
23
|
|
|
20
24
|
## MANDATORY SEQUENCE
|
|
21
25
|
|
|
22
|
-
**
|
|
26
|
+
**Initialize workflow context defaults.** Before entering §1, set `confidence_mode = "normal"` as the default. §4 may upgrade this to `"degraded — all findings T1-low"` if the operator opts into degraded mode. Downstream steps (report.md, drift-report-template.md) consume this variable directly — no conditional at the usage site.
|
|
23
27
|
|
|
24
28
|
### 1. Get Skill Path
|
|
25
29
|
|
|
@@ -53,7 +57,7 @@ Which skill would you like to audit? Please provide the skill name or path."
|
|
|
53
57
|
|
|
54
58
|
3. If not in manifest: check for `active` symlink at `{skills_output_folder}/{skill_name}/active` — resolve to `{skill_group}/active/{skill_name}/`
|
|
55
59
|
4. If neither: fall back to flat path `{skills_output_folder}/{skill_name}/`. If SKILL.md exists at the flat path, auto-migrate per `knowledge/version-paths.md` migration rules
|
|
56
|
-
5. Store the resolved path as `{resolved_skill_package}`. Also store `audit_target_version` = the version that was actually selected (manifest, symlink, or flat) for step
|
|
60
|
+
5. Store the resolved path as `{resolved_skill_package}`. Also store `audit_target_version` = the version that was actually selected (manifest, symlink, or flat) for step 6 Provenance to surface. When the gate above fired, also record the rejected version under `manifest_symlink_drift = {manifest: {active_version}, symlink: {symlink_target}, audited: {audit_target_version}, reason: {fresher-provenance|operator-choice|headless-default}}` so reviewers can audit the choice.
|
|
57
61
|
|
|
58
62
|
**If user provides full path:**
|
|
59
63
|
- Use as provided
|
|
@@ -88,29 +92,38 @@ Load the following from the skill directory:
|
|
|
88
92
|
- `name`, `version`, `generation_date`, `confidence_tier` used during creation
|
|
89
93
|
- `source_root` — Resolved source code path used during extraction
|
|
90
94
|
|
|
91
|
-
**Detect split-body state:** If a `references/` directory exists and SKILL.md's `## Full` headings are absent or stubs, this is a split-body skill. Flag `split_body: true` in the baseline so downstream steps (especially semantic diff in step
|
|
95
|
+
**Detect split-body state:** If a `references/` directory exists and SKILL.md's `## Full` headings are absent or stubs, this is a split-body skill. Flag `split_body: true` in the baseline so downstream steps (especially semantic diff in step 4) know to also read `references/*.md` for complete content comparison.
|
|
92
96
|
|
|
93
97
|
### 4. Load Provenance Map
|
|
94
98
|
|
|
95
99
|
Search for provenance map at `{forge_data_folder}/{skill_name}/{active_version}/provenance-map.json` (i.e., `{forge_version}/provenance-map.json`). If not found at the versioned path, fall back to `{forge_data_folder}/{skill_name}/provenance-map.json`:
|
|
96
100
|
|
|
97
101
|
**If found:**
|
|
98
|
-
-
|
|
99
|
-
-
|
|
102
|
+
- Record provenance map age (days since last extraction) from file mtime
|
|
103
|
+
- Normalize the map's deterministic projections in one subprocess call:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
uv run {loadProvenanceScript} normalize {provenanceMap}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Parse the emitted JSON and stash these fields in workflow context (downstream steps read them directly — no re-walk):
|
|
110
|
+
- `{bounded_scan_files}` — sorted POSIX list, union of `entries[].source_file` and `file_entries[].source_file`. Step 2 `re-index.md` consumes this as the bounded scan list.
|
|
111
|
+
- `{is_stack_skill}`, `{legacy_stack_provenance}` — stack-skill flags (see Stack Skill Detection below for downstream branching).
|
|
112
|
+
- `{source_root}`, `{baseline_commit}`, `{baseline_ref}` — used by §5 Resolve Source Path and §5b Detect Upstream Drift.
|
|
113
|
+
- `{reexport_map}` — `{<internal>: <public>}` mapping consumed by `structural-diff.md` §1 to collapse public-API renames before diffing.
|
|
114
|
+
|
|
115
|
+
If the script exits non-zero, surface the stderr as a HARD HALT — the map is structurally invalid and downstream steps cannot proceed.
|
|
100
116
|
|
|
101
117
|
**If missing at both paths:**
|
|
102
118
|
- "No provenance map found for `{skill_name}`. This skill may not have been created by create-skill."
|
|
103
119
|
- "**Degraded mode available:** I can perform text-based comparison without provenance data. Findings will have T1-low confidence."
|
|
104
120
|
- "**[D]egraded mode** — proceed with text-diff only"
|
|
105
121
|
- "**[X]** — abort audit"
|
|
106
|
-
- Wait for user selection. If D, set `degraded_mode: true
|
|
122
|
+
- Wait for user selection. If D, set `degraded_mode: true` and `confidence_mode = "degraded — all findings T1-low"`, then skip the normalize call above (no map to normalize). If X, halt workflow.
|
|
107
123
|
|
|
108
124
|
### Stack Skill Detection
|
|
109
125
|
|
|
110
|
-
|
|
111
|
-
- If `provenance_version` is `"2.0"` and `skill_type` is `"stack"`: set `{is_stack_skill}` = true
|
|
112
|
-
- If provenance-map has top-level `libraries` key (v1 stack format): set `{is_stack_skill}` = true, `{legacy_stack_provenance}` = true
|
|
113
|
-
- Otherwise: `{is_stack_skill}` = false
|
|
126
|
+
`{is_stack_skill}` and `{legacy_stack_provenance}` are already resolved by the normalize call in §4 — no additional walk needed. Apply the post-detection logic:
|
|
114
127
|
|
|
115
128
|
If `{is_stack_skill}` is true and `constituents` array is present (compose-mode stack):
|
|
116
129
|
- For each constituent, compute the current metadata hash: read `{constituent.skill_path}/active/{constituent.skill_name}/metadata.json` and compute SHA-256
|
|
@@ -123,10 +136,9 @@ If `{legacy_stack_provenance}` is true: log a note that this stack uses v1 prove
|
|
|
123
136
|
### 5. Resolve Source Path
|
|
124
137
|
|
|
125
138
|
**If provenance map loaded:**
|
|
126
|
-
- Use `source_root`
|
|
139
|
+
- Use `{source_root}` (already extracted by §4 normalize) as source code path
|
|
127
140
|
- Verify source path still exists and is accessible
|
|
128
|
-
-
|
|
129
|
-
- Extract `baseline_ref` = `metadata.source_ref` (may be a tag, branch, `HEAD`, or `"local"`)
|
|
141
|
+
- `{baseline_commit}` and `{baseline_ref}` are already populated by §4. If `{baseline_commit}` is null in the projection, fall back to `metadata.source_commit`. `{baseline_ref}` may be a tag, branch, `HEAD`, or `"local"`.
|
|
130
142
|
|
|
131
143
|
**If degraded mode:**
|
|
132
144
|
- Ask user: "Please provide the path to the current source code."
|
|
@@ -144,7 +156,7 @@ Upstream drift detection is the primary use case of this workflow. If the local
|
|
|
144
156
|
- `baseline_commit` is unavailable
|
|
145
157
|
- Degraded mode is active (no provenance map)
|
|
146
158
|
|
|
147
|
-
When skipping, log the reason, then set the audit-ref context variables to baseline values so step
|
|
159
|
+
When skipping, log the reason, then set the audit-ref context variables to baseline values so step 6 renders a coherent Provenance row: `audit_ref = baseline_ref or "(unknown)"`, `audit_ref_source = "baseline"` (or `"unavailable"` if both `baseline_ref` and `baseline_commit` are unset), `audit_commit = baseline_commit or "(unknown)"`, `latest_tag = null`, `remote_head = null`. Continue to §6.
|
|
148
160
|
|
|
149
161
|
**Otherwise:**
|
|
150
162
|
|
|
@@ -198,16 +210,16 @@ When skipping, log the reason, then set the audit-ref context variables to basel
|
|
|
198
210
|
- **[F] Force checkout** — `git checkout --force` discards uncommitted changes irrecoverably. Only choose this after confirming the changes are safe to lose."
|
|
199
211
|
|
|
200
212
|
**Gate handling:**
|
|
201
|
-
- **[T]:** Run `git -C {source_root} stash push -m 'skf-audit-skill: pre-checkout {chosen_ref}' --include-untracked`. Capture the stash ref from the command output (e.g. `stash@{0}`) and store as `pre_checkout_stash_ref` in workflow context for step
|
|
213
|
+
- **[T]:** Run `git -C {source_root} stash push -m 'skf-audit-skill: pre-checkout {chosen_ref}' --include-untracked`. Capture the stash ref from the command output (e.g. `stash@{0}`) and store as `pre_checkout_stash_ref` in workflow context for step 6 Provenance to surface. Proceed to the checkout. (After audit completes, the operator restores the stash with `git stash pop` — step 6 puts the literal command in the report as a workflow-level convention rather than per-author ad-hoc prose.)
|
|
202
214
|
- **[A]:** HALT the workflow. Do not write a drift report — the audit was never started.
|
|
203
|
-
- **[F]:** Run `git -C {source_root} checkout --force {chosen_ref}` instead of the plain checkout. Record `pre_checkout_force_discard: true` in workflow context for step
|
|
215
|
+
- **[F]:** Run `git -C {source_root} checkout --force {chosen_ref}` instead of the plain checkout. Record `pre_checkout_force_discard: true` in workflow context for step 6 to surface as a loud warning. Skip the stash path.
|
|
204
216
|
- **Other input:** help user, redisplay the sub-gate.
|
|
205
217
|
|
|
206
218
|
**Headless default** (when `{headless_mode}`): auto-select **[A] Abort** rather than silently mutating the working tree. Emit a loud log line: `"headless: dirty worktree detected at {source_root}; refusing to checkout {chosen_ref} or stash. Re-run interactively to choose [T]/[A]/[F]."` Stashing under automation could lose work if the operator never returns to pop; force-checkout under automation could destroy uncommitted work outright. Abort is the only safe non-interactive default.
|
|
207
219
|
|
|
208
220
|
If `git status --porcelain` is empty, skip the sub-gate and proceed directly to the checkout.
|
|
209
221
|
|
|
210
|
-
Then `git -C {source_root} checkout {chosen_ref}` (prefer `latest_tag` when present, else `remote_head`). Set `audit_ref = {chosen_ref}`, `audit_ref_source = "checkout-latest"`, `audit_commit = git rev-parse HEAD`. Hold the lock through step
|
|
222
|
+
Then `git -C {source_root} checkout {chosen_ref}` (prefer `latest_tag` when present, else `remote_head`). Set `audit_ref = {chosen_ref}`, `audit_ref_source = "checkout-latest"`, `audit_commit = git rev-parse HEAD`. Hold the lock through step 2 re-extraction and release only after the extraction snapshot is complete.
|
|
211
223
|
- **[S]:** Keep baseline. Set `audit_ref = baseline_ref`, `audit_ref_source = "baseline"`, `audit_commit = baseline_commit`.
|
|
212
224
|
- **[X]:** HALT workflow — do not create drift report.
|
|
213
225
|
- **Other input:** help user, redisplay gate.
|
|
@@ -218,10 +230,36 @@ When skipping, log the reason, then set the audit-ref context variables to basel
|
|
|
218
230
|
|
|
219
231
|
### 6. Create Drift Report
|
|
220
232
|
|
|
233
|
+
**Re-audit detection (before creating a fresh report).** Glob `{forge_version}/drift-report-*.md`. If one or more matches exist, identify the most recent one by file mtime (or by the `{timestamp}` segment in the filename when mtime is unreliable on the filesystem). If that report's age is `< 7 days` and its frontmatter `audit_ref` matches the current `{audit_ref}` (resolved in §5b), surface a soft gate before creating a fresh report:
|
|
234
|
+
|
|
235
|
+
"**Recent audit found:** `{prior_report_path}` (created {prior_timestamp}, audit_ref=`{audit_ref}`).
|
|
236
|
+
|
|
237
|
+
Options:
|
|
238
|
+
- **[F] Fresh audit** (recommended; default in headless) — start a new drift report at `{outputFile}` and ignore the prior run.
|
|
239
|
+
- **[D] Diff against prior report** — compute findings delta vs the prior report and emit a `## Diff Against Prior Report` subsection in step 6 (report.md).
|
|
240
|
+
- **[R] Resume the prior report** — load the prior report's frontmatter (`stepsCompleted`, `drift_score`, intermediate findings) and jump to the next un-completed step instead of starting over.
|
|
241
|
+
|
|
242
|
+
**Select:** [F] / [D] / [R]"
|
|
243
|
+
|
|
244
|
+
**Gate handling:**
|
|
245
|
+
- **[F]:** Default. Proceed with the fresh-report creation below — ignore the prior report.
|
|
246
|
+
- **[D]:** Read the prior report's findings_list (parse the Structural/Semantic/Severity sections, or the appended findings tables) and stash as `prior_findings` in workflow context. Run the new audit normally. In step 6 (report.md), after the Remediation Suggestions section, emit a `## Diff Against Prior Report` subsection summarizing added / removed / changed findings vs `prior_findings`.
|
|
247
|
+
- **[R]:** Load the prior report's frontmatter (`stepsCompleted`, `drift_score`, any intermediate state). Set `{outputFile}` to the prior report path (do NOT create a new one). Determine the next un-completed step from `stepsCompleted` and skip forward to it; downstream steps append to the existing report.
|
|
248
|
+
|
|
249
|
+
> **Note (resumability):** the existing template frontmatter captures `stepsCompleted` and `drift_score` but does not currently persist intermediate findings_list between stages. If [R] is selected and stepsCompleted indicates the prior run halted after structural-diff or semantic-diff, the appended sections in the report body (`## Structural Drift`, `## Semantic Drift`, `## Severity Classification`) serve as the implicit intermediate state — re-parse them on resume rather than re-running completed stages. **TODO:** if resumability proves unreliable in practice, extend the report frontmatter to carry an explicit `intermediate_findings` block (out of scope for this PR).
|
|
250
|
+
|
|
251
|
+
- **Other input:** help user, redisplay the gate.
|
|
252
|
+
|
|
253
|
+
**Headless default** (when `{headless_mode}`): auto-select **[F]** and emit a loud log line: `"headless: recent audit found at {prior_report_path}; defaulting to fresh audit. Re-run interactively to choose [D]/[R]."`
|
|
254
|
+
|
|
255
|
+
**Skip this gate** if no prior report matches the `< 7 days + same audit_ref` filter — proceed directly to creating the fresh report.
|
|
256
|
+
|
|
257
|
+
**Create the fresh report** (when [F] is selected, headless default fires, or no prior report exists):
|
|
258
|
+
|
|
221
259
|
Create `{outputFile}` from `{templateFile}`:
|
|
222
260
|
|
|
223
261
|
- Populate frontmatter: skill_name, skill_path, source_path, forge_tier, date, user_name
|
|
224
|
-
- Set `stepsCompleted: ['
|
|
262
|
+
- Set `stepsCompleted: ['init']`
|
|
225
263
|
- Fill Audit Summary skeleton with loaded baseline data
|
|
226
264
|
|
|
227
265
|
### 7. Present Baseline Summary (User Gate)
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
---
|
|
2
|
-
nextStepFile: '
|
|
2
|
+
nextStepFile: 'structural-diff.md'
|
|
3
3
|
outputFile: '{forge_version}/drift-report-{timestamp}.md'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
+
<!-- Config: communicate in {communication_language}. -->
|
|
7
|
+
|
|
6
8
|
# Step 2: Re-Index Source
|
|
7
9
|
|
|
8
10
|
## STEP GOAL:
|
|
@@ -17,8 +19,6 @@ Re-scan the source code using the current forge tier tools to build a fresh extr
|
|
|
17
19
|
|
|
18
20
|
## MANDATORY SEQUENCE
|
|
19
21
|
|
|
20
|
-
**CRITICAL:** Follow this sequence exactly. Do not skip, reorder, or improvise unless user explicitly requests a change.
|
|
21
|
-
|
|
22
22
|
### 1. Determine Extraction Strategy
|
|
23
23
|
|
|
24
24
|
Based on forge tier detected in Step 01:
|
|
@@ -47,23 +47,23 @@ Based on forge tier detected in Step 01:
|
|
|
47
47
|
|
|
48
48
|
### 2. Build Bounded Scan List
|
|
49
49
|
|
|
50
|
-
Audit-skill detects drift on files that were in scope during create-skill. The authoritative record of "what was in scope" is the provenance map loaded in step
|
|
50
|
+
Audit-skill detects drift on files that were in scope during create-skill. The authoritative record of "what was in scope" is the provenance map loaded in step 1. Scan only those files — **audit-skill does NOT discover new files**. New-file detection is the responsibility of `skf-update-skill`, which maintains its own change manifest. To audit a project that has grown new files since creation, run update-skill first, then audit-skill.
|
|
51
51
|
|
|
52
|
-
**Why bounded:** without this constraint, files that were deliberately excluded by the original brief's scope patterns (test fixtures, vendored code, generated artifacts, demo code, unrelated modules) get scanned on every audit and their exports are flagged by step
|
|
52
|
+
**Why bounded:** without this constraint, files that were deliberately excluded by the original brief's scope patterns (test fixtures, vendored code, generated artifacts, demo code, unrelated modules) get scanned on every audit and their exports are flagged by step 3 structural diff as "added" — false-positive drift that obscures real structural changes.
|
|
53
53
|
|
|
54
|
-
**If a provenance map was loaded in step
|
|
54
|
+
**If a provenance map was loaded in step 1** (normal mode):
|
|
55
55
|
|
|
56
56
|
1. Extract the unique set of file paths from the provenance map:
|
|
57
57
|
- `entries[].source_file` (one path per extracted export)
|
|
58
58
|
- `file_entries[].source_file` (one path per tracked script/asset, when present)
|
|
59
59
|
2. Deduplicate the combined list. This is the **bounded scan list**.
|
|
60
|
-
3. Verify each path under `{source_root}`. Files that existed at creation time but are now missing are **not** errors at this stage — keep them in the list so step
|
|
60
|
+
3. Verify each path under `{source_root}`. Files that existed at creation time but are now missing are **not** errors at this stage — keep them in the list so step 3 can classify them as DELETED. Handling missing files is step 3's job, not step 2's.
|
|
61
61
|
4. Record `bounded_scan: true` and `bounded_scan_source: "provenance-map"` in context for the evidence report.
|
|
62
62
|
5. Report:
|
|
63
63
|
|
|
64
64
|
"**Bounded scan:** {count} files from provenance map ({provenance_date})."
|
|
65
65
|
|
|
66
|
-
**If degraded mode** (no provenance map was loaded — user confirmed `[D]egraded mode` at step
|
|
66
|
+
**If degraded mode** (no provenance map was loaded — user confirmed `[D]egraded mode` at step 1 §4):
|
|
67
67
|
|
|
68
68
|
1. Fall back to a source-tree scan: list all source files under `{source_root}` matching the project's primary language extensions (derive from `metadata.json.language` — e.g., `*.ts` / `*.tsx` for typescript, `*.py` for python, `*.rs` for rust, `*.go` for go).
|
|
69
69
|
2. Apply generic exclusions: `**/tests/**`, `**/test/**`, `**/__tests__/**`, `*.test.*`, `*.spec.*`, `node_modules/**`, `dist/**`, `build/**`, `target/**`, `__pycache__/**`, `.venv/**`, `vendor/**`.
|
|
@@ -82,7 +82,7 @@ Audit-skill detects drift on files that were in scope during create-skill. The a
|
|
|
82
82
|
3. Records: export name, type, signature, file path, line number, confidence tier
|
|
83
83
|
4. Returns structured findings to parent
|
|
84
84
|
|
|
85
|
-
**If a file from the bounded scan list is missing on disk:** record `{file, exports: [], status: "missing"}` and continue — step
|
|
85
|
+
**If a file from the bounded scan list is missing on disk:** record `{file, exports: [], status: "missing"}` and continue — step 3 structural diff will classify exports previously at this path as DELETED.
|
|
86
86
|
|
|
87
87
|
**If subprocess unavailable:** Perform extraction in main thread, processing each file sequentially.
|
|
88
88
|
|
|
@@ -116,7 +116,7 @@ Read the `qmd_collections` registry from `{sidecar_path}/forge-tier.yaml`.
|
|
|
116
116
|
|
|
117
117
|
Find the collection entry matching the current skill: look for an entry where `skill_name` matches the current skill being audited AND `type` is `"extraction"`.
|
|
118
118
|
|
|
119
|
-
Three collection states must be handled distinctly (same branching as step
|
|
119
|
+
Three collection states must be handled distinctly (same branching as step 4 §2 — keep them in sync):
|
|
120
120
|
|
|
121
121
|
**If a matching extraction collection is found and populated** (pre-query probe via `qmd ls {collection_name}` or equivalent returns one or more files):
|
|
122
122
|
Query qmd_bridge against the `{skill_name}-extraction` collection for temporal context on each extracted export:
|
|
@@ -175,7 +175,7 @@ CCC failures: skip rename detection silently, proceed with standard structural d
|
|
|
175
175
|
### 6. Update Report and Auto-Proceed
|
|
176
176
|
|
|
177
177
|
Update {outputFile} frontmatter:
|
|
178
|
-
- Append `'
|
|
178
|
+
- Append `'re-index'` to `stepsCompleted`
|
|
179
179
|
|
|
180
180
|
### 7. Present MENU OPTIONS
|
|
181
181
|
|