bmad-module-skill-forge 2.2.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/README.md +49 -49
- package/docs/404.md +10 -8
- package/docs/_data/pinned.yaml +22 -13
- package/docs/_internal/STABILITY.md +58 -35
- package/docs/agents.md +39 -53
- package/docs/architecture.md +65 -51
- package/docs/bmad-synergy.md +53 -51
- package/docs/campaign.md +127 -75
- package/docs/concepts.md +34 -28
- package/docs/examples.md +70 -68
- package/docs/forge-auto.md +34 -31
- package/docs/getting-started.md +118 -57
- package/docs/how-it-works.md +25 -21
- package/docs/index.md +15 -15
- package/docs/skill-model.md +70 -59
- package/docs/troubleshooting.md +135 -18
- package/docs/verifying-a-skill.md +83 -57
- package/docs/why-skf.md +24 -22
- package/docs/workflows.md +274 -110
- package/package.json +18 -10
- package/src/forger/preferences.yaml +8 -1
- package/src/knowledge/agentskills-spec.md +2 -0
- package/src/knowledge/ccc-bridge.md +40 -24
- package/src/knowledge/confidence-tiers.md +9 -5
- package/src/knowledge/overview.md +3 -3
- package/src/knowledge/progressive-capability.md +8 -8
- package/src/knowledge/provenance-tracking.md +9 -5
- package/src/knowledge/qmd-registry.md +2 -2
- package/src/knowledge/skf-knowledge-index.csv +2 -2
- package/src/knowledge/skill-lifecycle.md +18 -11
- package/src/knowledge/split-body-strategy.md +0 -3
- package/src/knowledge/tool-resolution.md +4 -2
- package/src/knowledge/version-paths.md +101 -15
- package/src/module-help.csv +3 -3
- package/src/module.yaml +10 -0
- package/src/shared/data/ast-grep-recipes.yaml +608 -0
- package/src/shared/data/ide-context-files.json +30 -0
- package/src/shared/health-check.md +32 -12
- package/src/shared/references/description-guard-protocol.md +12 -9
- package/src/shared/references/feasibility-report-schema.md +19 -13
- package/src/shared/references/headless-gate-convention.md +55 -3
- package/src/shared/references/output-contract-schema.md +19 -8
- package/src/shared/references/pipeline-contracts.md +94 -29
- package/src/shared/references/tessl-review.md +77 -0
- package/src/shared/scripts/schemas/skf-analyze-result-envelope.v1.json +194 -0
- package/src/shared/scripts/schemas/skf-audit-result-envelope.v1.json +192 -0
- package/src/shared/scripts/schemas/skf-brief-result-envelope.v1.json +32 -4
- package/src/shared/scripts/schemas/skf-campaign-result-envelope.v1.json +174 -0
- package/src/shared/scripts/schemas/skf-create-skill-result-envelope.v1.json +284 -0
- package/src/shared/scripts/schemas/skf-drop-skill-result-envelope.v1.json +164 -0
- package/src/shared/scripts/schemas/skf-export-result-envelope.v1.json +160 -0
- package/src/shared/scripts/schemas/skf-quick-skill-result-envelope.v1.json +261 -0
- package/src/shared/scripts/schemas/skf-refine-architecture-result-envelope.v1.json +192 -0
- package/src/shared/scripts/schemas/skf-rename-skill-result-envelope.v1.json +179 -0
- package/src/shared/scripts/schemas/skf-setup-result-envelope.v1.json +27 -11
- package/src/shared/scripts/schemas/skf-stack-result-envelope.v1.json +176 -0
- package/src/shared/scripts/schemas/skf-test-result-envelope.v1.json +173 -0
- package/src/shared/scripts/schemas/skf-update-result-envelope.v1.json +19 -5
- package/src/shared/scripts/schemas/skf-verify-stack-result-envelope.v1.json +180 -0
- package/src/shared/scripts/schemas/skill-brief.v1.json +34 -0
- package/src/shared/scripts/schemas/workspace-detection.v1.json +1 -1
- package/src/shared/scripts/skf-atomic-write.py +30 -14
- package/src/shared/scripts/skf-build-change-manifest.py +2203 -24
- package/src/shared/scripts/skf-ccc-git-hygiene.py +532 -0
- package/src/shared/scripts/skf-check-unit-records.py +184 -0
- package/src/shared/scripts/skf-check-workspace-drift.py +538 -9
- package/src/shared/scripts/skf-classify-changed-files.py +694 -0
- package/src/shared/scripts/skf-comention-pairs.py +1333 -123
- package/src/shared/scripts/skf-compare-file-hashes.py +1 -1
- package/src/shared/scripts/skf-count-imports.py +1867 -0
- package/src/shared/scripts/skf-count-tokens.py +1 -1
- package/src/shared/scripts/skf-derive-assembly-shape.py +3 -2
- package/src/shared/scripts/skf-description-guard.py +99 -11
- package/src/shared/scripts/skf-detect-docs.py +694 -2
- package/src/shared/scripts/skf-detect-language.py +486 -107
- package/src/shared/scripts/skf-detect-registry.py +887 -0
- package/src/shared/scripts/skf-detect-scripts-assets.py +1 -1
- package/src/shared/scripts/skf-detect-tools.py +209 -27
- package/src/shared/scripts/skf-detect-workspaces.py +506 -30
- package/src/shared/scripts/skf-disqualify-candidates.py +821 -182
- package/src/shared/scripts/skf-emit-brief-result-envelope.py +69 -191
- package/src/shared/scripts/skf-emit-result-envelope.py +1604 -106
- package/src/shared/scripts/skf-enumerate-stack-skills.py +986 -117
- package/src/shared/scripts/skf-extract-public-api.py +4084 -85
- package/src/shared/scripts/skf-extraction-inventory.py +746 -0
- package/src/shared/scripts/skf-extraction-snapshot.py +539 -0
- package/src/shared/scripts/skf-fetch-temporal.py +674 -0
- package/src/shared/scripts/skf-find-cycles.py +97 -29
- package/src/shared/scripts/skf-find-test-report.py +476 -0
- package/src/shared/scripts/skf-forge-tier-rw.py +444 -203
- package/src/shared/scripts/skf-github-fetch.py +365 -0
- package/src/shared/scripts/skf-github-probe.py +661 -0
- package/src/shared/scripts/skf-hash-content.py +166 -12
- package/src/shared/scripts/skf-language-corpora.py +1 -1
- package/src/shared/scripts/skf-load-provenance.py +159 -27
- package/src/shared/scripts/skf-manifest-ops.py +1 -1
- package/src/shared/scripts/skf-merge-ccc-exclusions.py +2307 -223
- package/src/shared/scripts/skf-merge-doc-urls.py +1 -1
- package/src/shared/scripts/skf-names-present.py +221 -0
- package/src/shared/scripts/skf-pair-intersect.py +119 -28
- package/src/shared/scripts/skf-parse-gaps.py +1384 -0
- package/src/shared/scripts/skf-preapply.py +1 -1
- package/src/shared/scripts/skf-preflight.py +161 -27
- package/src/shared/scripts/skf-promote-staged.py +430 -0
- package/src/shared/scripts/skf-provenance-gap-dispatch.py +39 -7
- package/src/shared/scripts/skf-qmd-classify-collections.py +229 -45
- package/src/shared/scripts/skf-quick-batch.py +774 -0
- package/src/shared/scripts/skf-rebuild-managed-sections.py +972 -88
- package/src/shared/scripts/skf-recommend-scope-type.py +323 -156
- package/src/shared/scripts/skf-render-metadata-stats.py +156 -12
- package/src/shared/scripts/skf-render-quick-metadata.py +132 -28
- package/src/shared/scripts/skf-render-stack-metadata.py +976 -0
- package/src/shared/scripts/skf-resolve-authoritative-files.py +128 -13
- package/src/shared/scripts/skf-resolve-package.py +523 -106
- package/src/shared/scripts/skf-rewrite-skill-name.py +433 -47
- package/src/shared/scripts/skf-run-lock.py +577 -0
- package/src/shared/scripts/skf-scan-manifests.py +998 -57
- package/src/shared/scripts/skf-scan-skill-md-structure.py +1341 -37
- package/src/shared/scripts/skf-severity-classify.py +712 -108
- package/src/shared/scripts/skf-shape-detect.py +298 -204
- package/src/shared/scripts/skf-shard-body.py +9 -8
- package/src/shared/scripts/skf-skill-inventory.py +2412 -89
- package/src/shared/scripts/skf-skills-module.py +472 -0
- package/src/shared/scripts/skf-source-tree.py +1796 -0
- package/src/shared/scripts/skf-structural-diff.py +670 -119
- package/src/shared/scripts/skf-tessl-review.py +706 -0
- package/src/shared/scripts/skf-update-active-symlink.py +5 -5
- package/src/shared/scripts/skf-update-run-state.py +624 -0
- package/src/shared/scripts/skf-validate-brief-inputs.py +92 -29
- package/src/shared/scripts/skf-validate-brief-schema.py +4 -1
- package/src/shared/scripts/skf-validate-feasibility-report.py +577 -66
- package/src/shared/scripts/skf-validate-frontmatter.py +103 -26
- package/src/shared/scripts/skf-validate-output.py +712 -64
- package/src/shared/scripts/skf-validate-pins.py +1 -1
- package/src/shared/scripts/skf-verify-no-trace.py +116 -10
- package/src/shared/scripts/skf-verify-provenance-completeness.py +2919 -54
- package/src/shared/scripts/skf-write-skill-brief.py +367 -19
- package/src/shared/tool-requirements.yaml +201 -0
- package/src/skf-analyze-source/SKILL.md +41 -36
- package/src/skf-analyze-source/assets/skill-brief-schema.md +7 -8
- package/src/skf-analyze-source/customize.toml +36 -24
- package/src/skf-analyze-source/references/auto-docs-only.md +58 -20
- package/src/skf-analyze-source/references/continue.md +2 -13
- package/src/skf-analyze-source/references/discover-additional-source.md +147 -0
- package/src/skf-analyze-source/references/generate-briefs.md +121 -55
- package/src/skf-analyze-source/references/headless-contract.md +42 -15
- package/src/skf-analyze-source/references/identify-units.md +96 -110
- package/src/skf-analyze-source/references/init.md +73 -71
- package/src/skf-analyze-source/references/map-and-detect.md +123 -105
- package/src/skf-analyze-source/references/map-unit-exports.md +68 -0
- package/src/skf-analyze-source/references/recommend.md +51 -70
- package/src/skf-analyze-source/references/scan-project.md +60 -84
- package/src/skf-analyze-source/references/scan-root.md +39 -0
- package/src/skf-analyze-source/references/step-auto-scope-coexistence.md +47 -0
- package/src/skf-analyze-source/references/step-auto-scope-corpora.md +53 -0
- package/src/skf-analyze-source/references/step-auto-scope-split.md +91 -0
- package/src/skf-analyze-source/references/step-auto-scope.md +208 -293
- package/src/skf-analyze-source/references/step-shape-detect.md +14 -12
- package/src/skf-analyze-source/references/unit-detection-heuristics.md +37 -42
- package/src/skf-audit-skill/SKILL.md +43 -51
- package/src/skf-audit-skill/assets/drift-report-template.md +27 -3
- package/src/skf-audit-skill/customize.toml +41 -20
- package/src/skf-audit-skill/references/constituent-freshness.md +91 -0
- package/src/skf-audit-skill/references/doc-drift.md +141 -0
- package/src/skf-audit-skill/references/headless-contract.md +29 -0
- package/src/skf-audit-skill/references/init.md +148 -210
- package/src/skf-audit-skill/references/re-index.md +96 -108
- package/src/skf-audit-skill/references/report.md +96 -33
- package/src/skf-audit-skill/references/semantic-diff.md +27 -18
- package/src/skf-audit-skill/references/severity-classify.md +79 -65
- package/src/skf-audit-skill/references/severity-rules.md +15 -6
- package/src/skf-audit-skill/references/structural-diff.md +75 -90
- package/src/skf-audit-skill/references/upstream-checkout.md +77 -0
- package/src/skf-audit-skill/scripts/render-drift-tables.py +685 -0
- package/src/skf-brief-skill/SKILL.md +36 -25
- package/src/skf-brief-skill/assets/description-voice-examples.md +1 -1
- package/src/skf-brief-skill/assets/scope-templates.md +17 -24
- package/src/skf-brief-skill/assets/skill-brief-schema.md +29 -15
- package/src/skf-brief-skill/customize.toml +48 -20
- package/src/skf-brief-skill/references/analyze-target.md +142 -125
- package/src/skf-brief-skill/references/confirm-brief.md +10 -8
- package/src/skf-brief-skill/references/draft-checkpoint.md +36 -17
- package/src/skf-brief-skill/references/gather-intent-ratify.md +68 -0
- package/src/skf-brief-skill/references/gather-intent.md +87 -182
- package/src/skf-brief-skill/references/headless-args.md +84 -16
- package/src/skf-brief-skill/references/health-check.md +1 -1
- package/src/skf-brief-skill/references/invocation-contract.md +18 -13
- package/src/skf-brief-skill/references/portfolio-similarity-check.md +1 -1
- package/src/skf-brief-skill/references/qmd-collection-registration.md +7 -10
- package/src/skf-brief-skill/references/scope-definition.md +123 -47
- package/src/skf-brief-skill/references/step-auto-brief.md +24 -80
- package/src/skf-brief-skill/references/step-auto-validate.md +20 -121
- package/src/skf-brief-skill/references/version-resolution.md +3 -2
- package/src/skf-brief-skill/references/write-brief.md +66 -57
- package/src/skf-campaign/SKILL.md +31 -34
- package/src/skf-campaign/assets/campaign-state-schema.json +25 -4
- package/src/skf-campaign/customize.toml +47 -16
- package/src/skf-campaign/references/campaign-contracts.md +39 -29
- package/src/skf-campaign/references/campaign-directive-spec.md +4 -2
- package/src/skf-campaign/references/health-check.md +7 -16
- package/src/skf-campaign/references/step-01-setup.md +46 -84
- package/src/skf-campaign/references/step-02-strategy.md +31 -30
- package/src/skf-campaign/references/step-03-pins.md +26 -18
- package/src/skf-campaign/references/step-04-provenance.md +24 -23
- package/src/skf-campaign/references/step-05-skill-loop.md +67 -48
- package/src/skf-campaign/references/step-06-batch.md +41 -34
- package/src/skf-campaign/references/step-07-capstone.md +40 -25
- package/src/skf-campaign/references/step-08-verify.md +28 -29
- package/src/skf-campaign/references/step-09-refine.md +29 -30
- package/src/skf-campaign/references/step-10-export.md +48 -36
- package/src/skf-campaign/references/step-11-maintenance.md +31 -34
- package/src/skf-campaign/references/step-resume.md +37 -68
- package/src/skf-campaign/scripts/campaign-deps.py +57 -18
- package/src/skf-campaign/scripts/campaign-parse-manifest.py +361 -54
- package/src/skf-campaign/scripts/campaign-provenance.py +96 -53
- package/src/skf-campaign/scripts/campaign-quality-gate.py +592 -0
- package/src/skf-campaign/scripts/campaign-render-batch.py +257 -49
- package/src/skf-campaign/scripts/campaign-render-kickoff.py +343 -50
- package/src/skf-campaign/scripts/campaign-report.py +204 -37
- package/src/skf-campaign/scripts/campaign-state.py +1128 -0
- package/src/skf-campaign/scripts/campaign-status.py +10 -74
- package/src/skf-campaign/scripts/campaign-validate-pins.py +30 -3
- package/src/skf-campaign/scripts/campaign-validate-state.py +34 -4
- package/src/skf-campaign/templates/campaign-brief-template.yaml +4 -5
- package/src/skf-campaign/templates/campaign-report-template.md +5 -1
- package/src/skf-campaign/templates/kickoff-template.md +0 -14
- package/src/skf-create-skill/SKILL.md +27 -20
- package/src/skf-create-skill/assets/compile-assembly-rules.md +6 -5
- package/src/skf-create-skill/assets/skill-sections.md +15 -5
- package/src/skf-create-skill/customize.toml +20 -8
- package/src/skf-create-skill/references/authoritative-files-protocol.md +41 -42
- package/src/skf-create-skill/references/batch-mode.md +81 -0
- package/src/skf-create-skill/references/ccc-index-check.md +27 -0
- package/src/skf-create-skill/references/compile.md +107 -29
- package/src/skf-create-skill/references/component-extraction.md +113 -91
- package/src/skf-create-skill/references/enrich.md +41 -23
- package/src/skf-create-skill/references/entry-points-by-hand.md +20 -0
- package/src/skf-create-skill/references/extract.md +200 -161
- package/src/skf-create-skill/references/extraction-patterns-by-hand.md +141 -0
- package/src/skf-create-skill/references/extraction-patterns-tracing.md +2 -2
- package/src/skf-create-skill/references/extraction-patterns.md +584 -196
- package/src/skf-create-skill/references/generate-artifacts.md +145 -93
- package/src/skf-create-skill/references/health-check.md +1 -1
- package/src/skf-create-skill/references/load-brief.md +53 -36
- package/src/skf-create-skill/references/relabel-rule.md +12 -0
- package/src/skf-create-skill/references/report.md +28 -59
- package/src/skf-create-skill/references/source-resolution-protocols.md +49 -155
- package/src/skf-create-skill/references/step-auto-shard.md +20 -93
- package/src/skf-create-skill/references/step-doc-rot.md +44 -60
- package/src/skf-create-skill/references/step-doc-sources.md +28 -19
- package/src/skf-create-skill/references/sub/ccc-discover.md +18 -7
- package/src/skf-create-skill/references/sub/fetch-docs.md +106 -59
- package/src/skf-create-skill/references/sub/fetch-temporal.md +53 -166
- package/src/skf-create-skill/references/tier-degradation-rules.md +18 -9
- package/src/skf-create-skill/references/validate.md +173 -99
- package/src/skf-create-skill/scripts/scan-doc-rot.py +232 -99
- package/src/skf-create-stack-skill/SKILL.md +29 -56
- package/src/skf-create-stack-skill/assets/metadata-contract.md +51 -0
- package/src/skf-create-stack-skill/assets/provenance-map-schema.md +15 -15
- package/src/skf-create-stack-skill/assets/stack-skill-template.md +23 -57
- package/src/skf-create-stack-skill/customize.toml +23 -12
- package/src/skf-create-stack-skill/references/compile-stack.md +57 -66
- package/src/skf-create-stack-skill/references/compose-mode-rules.md +24 -44
- package/src/skf-create-stack-skill/references/detect-integrations.md +92 -95
- package/src/skf-create-stack-skill/references/detect-manifests.md +46 -71
- package/src/skf-create-stack-skill/references/generate-output.md +138 -128
- package/src/skf-create-stack-skill/references/init.md +90 -32
- package/src/skf-create-stack-skill/references/integration-patterns.md +1 -17
- package/src/skf-create-stack-skill/references/invocation-contract.md +34 -0
- package/src/skf-create-stack-skill/references/manifest-patterns.md +32 -20
- package/src/skf-create-stack-skill/references/parallel-extract.md +112 -38
- package/src/skf-create-stack-skill/references/rank-and-confirm.md +57 -75
- package/src/skf-create-stack-skill/references/report.md +39 -33
- package/src/skf-create-stack-skill/references/validate.md +20 -39
- package/src/skf-drop-skill/SKILL.md +28 -51
- package/src/skf-drop-skill/customize.toml +44 -30
- package/src/skf-drop-skill/references/execute.md +79 -146
- package/src/skf-drop-skill/references/invocation-contract.md +64 -0
- package/src/skf-drop-skill/references/report.md +46 -30
- package/src/skf-drop-skill/references/select.md +118 -124
- package/src/skf-drop-skill/scripts/dir-sizes.py +54 -26
- package/src/skf-drop-skill/scripts/drop-roster.py +322 -0
- package/src/skf-export-skill/SKILL.md +40 -62
- package/src/skf-export-skill/assets/managed-section-format.md +14 -50
- package/src/skf-export-skill/assets/snippet-format.md +3 -1
- package/src/skf-export-skill/customize.toml +42 -13
- package/src/skf-export-skill/references/generate-snippet.md +54 -46
- package/src/skf-export-skill/references/health-check.md +2 -0
- package/src/skf-export-skill/references/invocation-contract.md +15 -0
- package/src/skf-export-skill/references/load-skill.md +88 -62
- package/src/skf-export-skill/references/manifest-rebuild.md +9 -10
- package/src/skf-export-skill/references/multi-skill-mode.md +4 -4
- package/src/skf-export-skill/references/orphan-context-detection.md +13 -5
- package/src/skf-export-skill/references/orphan-row-detection.md +31 -22
- package/src/skf-export-skill/references/package.md +15 -73
- package/src/skf-export-skill/references/preflight-snippet-root-probe.md +51 -70
- package/src/skf-export-skill/references/result-envelope.md +31 -16
- package/src/skf-export-skill/references/summary.md +41 -17
- package/src/skf-export-skill/references/token-report.md +4 -12
- package/src/skf-export-skill/references/update-context.md +118 -237
- package/src/skf-forger/SKILL.md +61 -37
- package/src/skf-forger/bmad-skill-manifest.yaml +4 -1
- package/src/skf-forger/customize.toml +43 -0
- package/src/skf-forger/references/pipeline-mode.md +73 -18
- package/src/skf-forger/scripts/forge-status.py +299 -0
- package/src/skf-forger/scripts/parse-pipeline.py +322 -54
- package/src/skf-forger/scripts/pipeline-gate.py +428 -0
- package/src/skf-forger/scripts/pipeline-journal.py +1052 -0
- package/src/skf-quick-skill/SKILL.md +54 -53
- package/src/skf-quick-skill/assets/skill-template.md +4 -2
- package/src/skf-quick-skill/customize.toml +51 -20
- package/src/skf-quick-skill/references/batch-mode.md +74 -21
- package/src/skf-quick-skill/references/compile.md +30 -31
- package/src/skf-quick-skill/references/ecosystem-check.md +7 -57
- package/src/skf-quick-skill/references/finalize.md +69 -18
- package/src/skf-quick-skill/references/halt-contract.md +41 -29
- package/src/skf-quick-skill/references/health-check.md +5 -3
- package/src/skf-quick-skill/references/quick-extract.md +114 -45
- package/src/skf-quick-skill/references/registry-resolution.md +9 -64
- package/src/skf-quick-skill/references/resolve-target.md +116 -66
- package/src/skf-quick-skill/references/write-and-validate.md +79 -40
- package/src/skf-refine-architecture/SKILL.md +43 -53
- package/src/skf-refine-architecture/customize.toml +49 -20
- package/src/skf-refine-architecture/references/compile.md +97 -54
- package/src/skf-refine-architecture/references/exit-codes.md +30 -0
- package/src/skf-refine-architecture/references/finding-storage.md +21 -0
- package/src/skf-refine-architecture/references/gap-analysis.md +101 -38
- package/src/skf-refine-architecture/references/improvements.md +14 -20
- package/src/skf-refine-architecture/references/init.md +98 -57
- package/src/skf-refine-architecture/references/issue-detection.md +32 -39
- package/src/skf-refine-architecture/references/refinement-rules.md +37 -48
- package/src/skf-refine-architecture/references/report.md +65 -54
- package/src/skf-refine-architecture/scripts/skf-check-preservation.py +1619 -0
- package/src/skf-rename-skill/SKILL.md +19 -54
- package/src/skf-rename-skill/customize.toml +32 -26
- package/src/skf-rename-skill/references/execute.md +230 -184
- package/src/skf-rename-skill/references/exit-codes.md +7 -7
- package/src/skf-rename-skill/references/health-check.md +1 -7
- package/src/skf-rename-skill/references/invocation-contract.md +25 -0
- package/src/skf-rename-skill/references/report.md +63 -52
- package/src/skf-rename-skill/references/select.md +197 -115
- package/src/skf-rename-skill/scripts/skf-validate-rename-name.py +161 -21
- package/src/skf-setup/SKILL.md +26 -26
- package/src/skf-setup/customize.toml +14 -10
- package/src/skf-setup/references/auto-index.md +50 -63
- package/src/skf-setup/references/ccc-index.md +29 -90
- package/src/skf-setup/references/detect-and-tier.md +58 -67
- package/src/skf-setup/references/health-check.md +2 -0
- package/src/skf-setup/references/invocation-contract.md +14 -0
- package/src/skf-setup/references/report.md +43 -166
- package/src/skf-setup/references/tier-rules.md +5 -5
- package/src/skf-setup/references/write-config.md +34 -57
- package/src/skf-test-skill/SKILL.md +17 -57
- package/src/skf-test-skill/assets/output-section-formats.md +33 -34
- package/src/skf-test-skill/customize.toml +27 -13
- package/src/skf-test-skill/references/coherence-check.md +134 -62
- package/src/skf-test-skill/references/coverage-check-tiers.md +35 -0
- package/src/skf-test-skill/references/coverage-check.md +217 -254
- package/src/skf-test-skill/references/detect-mode.md +5 -5
- package/src/skf-test-skill/references/external-validators.md +94 -82
- package/src/skf-test-skill/references/health-check.md +6 -7
- package/src/skf-test-skill/references/init.md +163 -88
- package/src/skf-test-skill/references/invocation-contract.md +66 -0
- package/src/skf-test-skill/references/migration-section-rules.md +5 -2
- package/src/skf-test-skill/references/report.md +162 -142
- package/src/skf-test-skill/references/score.md +80 -107
- package/src/skf-test-skill/references/scoring-rules.md +41 -155
- package/src/skf-test-skill/references/source-access-protocol.md +19 -92
- package/src/skf-test-skill/references/step-hard-gate.md +51 -33
- package/src/skf-test-skill/scripts/aggregate-coherence.py +218 -30
- package/src/skf-test-skill/scripts/build-result-context.py +287 -0
- package/src/skf-test-skill/scripts/check-metadata-coherence.py +37 -4
- package/src/skf-test-skill/scripts/combine-external-scores.py +23 -6
- package/src/skf-test-skill/scripts/compute-score.py +223 -45
- package/src/skf-test-skill/scripts/gap-ledger.py +1381 -0
- package/src/skf-test-skill/scripts/hard-gate.py +203 -0
- package/src/skf-test-skill/scripts/load-coverage-inputs.py +760 -0
- package/src/skf-test-skill/scripts/locate-export-segments.py +835 -0
- package/src/skf-test-skill/scripts/reconcile-coverage.py +273 -79
- package/src/skf-test-skill/scripts/score-signatures.py +459 -0
- package/src/skf-test-skill/scripts/stage-helper-payload.py +148 -0
- package/src/skf-test-skill/scripts/validate-inventory.py +311 -16
- package/src/skf-test-skill/scripts/verify-declared-numerator.py +127 -52
- package/src/skf-test-skill/templates/test-report-template.md +21 -15
- package/src/skf-update-skill/SKILL.md +38 -25
- package/src/skf-update-skill/customize.toml +27 -12
- package/src/skf-update-skill/references/detect-changes.md +233 -222
- package/src/skf-update-skill/references/gap-driven.md +336 -0
- package/src/skf-update-skill/references/health-check.md +31 -5
- package/src/skf-update-skill/references/init.md +250 -84
- package/src/skf-update-skill/references/invocation-contract.md +12 -0
- package/src/skf-update-skill/references/manual-section-rules.md +6 -23
- package/src/skf-update-skill/references/merge.md +180 -47
- package/src/skf-update-skill/references/re-extract.md +53 -262
- package/src/skf-update-skill/references/report.md +100 -35
- package/src/skf-update-skill/references/write.md +331 -149
- package/src/skf-update-skill/scripts/skf-new-file-diff.py +29 -7
- package/src/skf-verify-stack/SKILL.md +23 -42
- package/src/skf-verify-stack/assets/feasibility-report-template.md +11 -5
- package/src/skf-verify-stack/customize.toml +55 -22
- package/src/skf-verify-stack/references/coverage-patterns.md +17 -8
- package/src/skf-verify-stack/references/coverage.md +67 -64
- package/src/skf-verify-stack/references/exit-codes.md +21 -8
- package/src/skf-verify-stack/references/init.md +107 -62
- package/src/skf-verify-stack/references/integration-verification-rules.md +12 -13
- package/src/skf-verify-stack/references/integrations.md +106 -65
- package/src/skf-verify-stack/references/report.md +59 -42
- package/src/skf-verify-stack/references/requirements.md +32 -9
- package/src/skf-verify-stack/references/synthesize.md +53 -39
- package/src/skf-verify-stack/scripts/skf-coverage-tally.py +398 -52
- package/src/skf-verify-stack/scripts/skf-previous-report.py +330 -0
- package/src/skf-verify-stack/scripts/skf-report-delta.py +453 -49
- package/src/skf-verify-stack/scripts/skf-verdict-rollup.py +240 -27
- package/tools/cli/commands/install.js +11 -4
- package/tools/cli/commands/status.js +15 -3
- package/tools/cli/commands/update.js +11 -4
- package/tools/cli/lib/tool-check.js +320 -0
- package/tools/cli/lib/version-check.js +22 -9
- package/tools/cli/skf-cli.js +4 -1
- package/.gitattributes +0 -16
- package/.nvmrc +0 -1
- package/docs/_internal/RELEASING.md +0 -679
- package/release-audits/v1.0.0-launch-audit.md +0 -728
- package/src/skf-audit-skill/references/step-doc-drift.md +0 -177
- package/src/skf-brief-skill/references/headless-source-authority-detection.md +0 -26
- package/src/skf-campaign/manifest.yaml +0 -15
- package/src/skf-create-skill/assets/tessl-dismissal-rules.md +0 -106
- package/src/skf-create-skill/references/ecosystem-check.md +0 -74
- package/src/skf-drop-skill/references/headless-contract.md +0 -18
- package/src/skf-update-skill/references/merge-conflict-rules.md +0 -15
- package/src/skf-update-skill/references/remote-source-resolution.md +0 -98
- package/src/skf-update-skill/references/validate.md +0 -124
- package/tools/validate-docs-drift.js +0 -233
- package/tools/validate-docs-links.js +0 -665
|
@@ -1,25 +1,26 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: skf-refine-architecture
|
|
3
|
-
description:
|
|
3
|
+
description: Refines an architecture document against generated skills and a Verify Stack report. Use when the user requests to "refine the architecture against generated skills" or "refine an architecture doc with a VS report."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Refine Architecture
|
|
7
7
|
|
|
8
8
|
## Overview
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Produces a refined architecture document: gaps filled, issues flagged and improvements suggested from the generated skills and an optional VS feasibility report. It never deletes original content, only adds annotations, subsections and suggestions between `<!-- RA:BEGIN ... -->` and `<!-- RA:END -->` marker lines; run again on a refined document, it sets its earlier annotations aside and writes one current set.
|
|
11
11
|
|
|
12
12
|
## Conventions
|
|
13
13
|
|
|
14
14
|
- Bare paths (e.g. `references/<name>.md`) resolve from the skill root.
|
|
15
|
-
-
|
|
15
|
+
- **Module-level path exception:** bare paths beginning with `knowledge/` or `shared/` resolve from the SKF module root (`{project-root}/_bmad/skf/` installed, `src/` in dev), not the skill root.
|
|
16
|
+
- **Sibling skills:** a path that names another SKF skill's folder (`skf-<name>/...`) resolves from the SKF module root, and that skill must be installed with this one.
|
|
16
17
|
- `{skill-root}` resolves to this skill's installed directory (where `customize.toml` lives, if present).
|
|
17
18
|
- `{project-root}`-prefixed paths resolve from the project working directory.
|
|
18
19
|
- `{skill-name}` resolves to the skill directory's basename.
|
|
19
20
|
|
|
20
21
|
## Role
|
|
21
22
|
|
|
22
|
-
You are an architecture refinement analyst
|
|
23
|
+
You are an architecture refinement analyst in Ferris Architect mode; the user brings the architecture vision and the generated skills.
|
|
23
24
|
|
|
24
25
|
## Workflow Rules
|
|
25
26
|
|
|
@@ -27,17 +28,18 @@ These rules apply to every step in this workflow:
|
|
|
27
28
|
|
|
28
29
|
- Never speculate — every gap, issue, or improvement must cite specific APIs, types, or function signatures from the generated skills
|
|
29
30
|
- Only load one step file at a time — never preload future steps
|
|
30
|
-
- If any instruction references a subprocess or tool you lack, achieve the outcome in your main context thread
|
|
31
31
|
- Always communicate in `{communication_language}`
|
|
32
32
|
- At any interactive prompt, the inputs `cancel`, `exit`, `[X]`, `q`, or `:q` exit cleanly with exit code 6 (`halt_reason: "user-cancelled"`)
|
|
33
|
-
- If `{headless_mode}` is true, auto-proceed through confirmation gates with their default action
|
|
33
|
+
- If `{headless_mode}` is true, auto-proceed through confirmation gates with their default action; a gate that picks its default records that decision in the run sink the moment it decides
|
|
34
|
+
- Every HARD HALT names its exit code, `halt_reason` and phase, and in headless mode prints the envelope the Result Contract below describes
|
|
35
|
+
- Run state lives in `{run_dir}`, not in context; step 6 deletes it when the run finishes, a HALT keeps it
|
|
34
36
|
|
|
35
37
|
## Stages
|
|
36
38
|
|
|
37
39
|
| # | Step | File | Auto-proceed |
|
|
38
40
|
|---|------|------|--------------|
|
|
39
|
-
| 1 | Initialize & Load Inputs | references/init.md | No (
|
|
40
|
-
| 2 | Gap Analysis | references/gap-analysis.md |
|
|
41
|
+
| 1 | Initialize & Load Inputs | references/init.md | No (input gate) |
|
|
42
|
+
| 2 | Gap Analysis | references/gap-analysis.md | Conditional (confirm a derived scope) |
|
|
41
43
|
| 3 | Issue Detection | references/issue-detection.md | Yes |
|
|
42
44
|
| 4 | Improvements | references/improvements.md | Yes |
|
|
43
45
|
| 5 | Compile Refined Architecture | references/compile.md | No (review) |
|
|
@@ -49,36 +51,14 @@ These rules apply to every step in this workflow:
|
|
|
49
51
|
| Aspect | Detail |
|
|
50
52
|
|--------|--------|
|
|
51
53
|
| **Inputs** | architecture_doc_path [required], vs_report_path [optional] |
|
|
52
|
-
| **Flags** | `--headless` / `-H
|
|
53
|
-
| **Gates** | step 1: Input Gate [use args] | step
|
|
54
|
-
| **Outputs** | `refined-architecture-{arch_project_name}.md` at `{outputFolderPath}` (
|
|
55
|
-
| **Headless** |
|
|
56
|
-
| **Exit codes** | See "Exit Codes" below |
|
|
57
|
-
|
|
58
|
-
## Exit Codes
|
|
59
|
-
|
|
60
|
-
Every HARD HALT in this workflow exits with a stable code so headless automators can branch on the failure class without grepping message text:
|
|
61
|
-
|
|
62
|
-
| Code | Meaning | Raised by |
|
|
63
|
-
| ---- | -------------------- | -------------------------------------------------------------------------------------------- |
|
|
64
|
-
| 0 | success | step 7 (terminal) |
|
|
65
|
-
| 2 | input-missing / input-invalid | step 1 §1 (headless missing `architecture-doc` arg, or invalid path) → `input-missing`; non-existent file → `input-invalid` |
|
|
66
|
-
| 3 | resolution-failure | On-Activation §5 (`output_folder` or `forge_data_folder` unconfigured) |
|
|
67
|
-
| 4 | write-failure | On-Activation §5 pre-flight write probe; step 1 §3c (RA state file write failed); step 5 §6 (refined-architecture write failed); step 6 §3 (result-contract write failed) |
|
|
68
|
-
| 5 | state-conflict | step 1 §3 (no skills found — refinement requires ≥1 skill) |
|
|
69
|
-
| 6 | user-cancelled | step 1 §1 prompt cancelled; any prompt that accepted `cancel`/`exit`/`:q`; step 5 review gate `[X]` |
|
|
70
|
-
| 7 | inventory-unreliable | step 1 §2 (>20% skill-inventory warnings exceed budget) |
|
|
71
|
-
| 8 | recovery-failed | step 5 §1 (durability state insufficient to reconstruct Step 02-04 findings); step 6 §1 (`## Refinement Summary` absent from the compiled document) |
|
|
54
|
+
| **Flags** | `--headless` / `-H`; `--architecture-doc <path>` and `--vs-report-path <path>` answer the step 1 prompts (`--vs-report-path none` refines without a report and skips the search for one); `--scope-skills <names>` (comma-separated skill names that replace the derived scope, so step 2 asks no scope confirmation) |
|
|
55
|
+
| **Gates** | step 1: Input Gate [use args] | step 2: Scope Confirm Gate [C] continue / [X] cancel (only when a derived scope drops skills or keeps an ambiguous one) | step 5: Review Gate [R] review each refinement / [C] approve and replace the refined document / [X] cancel |
|
|
56
|
+
| **Outputs** | `refined-architecture-{arch_project_name}.md` at `{outputFolderPath}` (the document's frontmatter `project_name`, else config's), promoted from a draft once the step 5 review approves it; an earlier one is first renamed to `refined-architecture-{arch_project_name}-{timestamp}.md`. Also `refine-architecture-result-{YYYYMMDD-HHmmss}.json`, its `-latest.json` copy and, once an approved review drops a finding, `.ra-dismissed-{arch_project_name}.json` |
|
|
57
|
+
| **Headless** | Every gate takes its default when `{headless_mode}` is true: `--scope-skills` skips the step 2 scope confirmation, and without `--vs-report-path` step 1 uses the [VS] report it finds. |
|
|
72
58
|
|
|
73
59
|
## Result Contract (Headless)
|
|
74
60
|
|
|
75
|
-
When `{headless_mode}` is true, step 6
|
|
76
|
-
|
|
77
|
-
```
|
|
78
|
-
SKF_REFINE_ARCHITECTURE_RESULT_JSON: {"status":"success|error","refined_path":"…|null","gap_count":0,"issue_count":0,"improvement_count":0,"exit_code":0,"halt_reason":null}
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
`status` is `"success"` on the terminal happy path, `"error"` on any HALT. `halt_reason` is one of: `null` (success), `"input-missing"`, `"input-invalid"`, `"insufficient-skills"`, `"output-folder-unconfigured"`, `"forge-folder-unconfigured"`, `"inventory-unreliable"`, `"write-failed"`, `"recovery-failed"`, `"user-cancelled"`. `exit_code` matches the table above.
|
|
61
|
+
When `{headless_mode}` is true, step 6 prints one `SKF_REFINE_ARCHITECTURE_RESULT_JSON: {...}` line on **stdout**, and every HARD HALT one on **stderr**, built by the shared emitter: `references/exit-codes.md` gives its fields, the `halt_reason` values and the halt command.
|
|
82
62
|
|
|
83
63
|
## On Activation
|
|
84
64
|
|
|
@@ -87,40 +67,42 @@ SKF_REFINE_ARCHITECTURE_RESULT_JSON: {"status":"success|error","refined_path":"
|
|
|
87
67
|
- `skills_output_folder`, `forge_data_folder`, `output_folder`, `sidecar_path`
|
|
88
68
|
|
|
89
69
|
2. **Compute run-scoped variables:**
|
|
90
|
-
- `timestamp` ←
|
|
70
|
+
- `timestamp` ← the output of `date -u +%Y%m%d-%H%M%S`, run once now: it names the run folder and the copy an earlier refined document is renamed to.
|
|
71
|
+
- `run_dir` ← `{project-root}/_bmad-output/.skf-run/skf-refine-architecture-{timestamp}`, the run folder §5 creates
|
|
91
72
|
|
|
92
73
|
3. **Resolve `{headless_mode}`**: true if `--headless` or `-H` was passed as an argument, or if `headless_mode: true` in `{sidecar_path}/preferences.yaml`. Default: false.
|
|
93
74
|
|
|
94
75
|
4. **Resolve workflow customization.** Run:
|
|
95
76
|
|
|
96
77
|
```bash
|
|
97
|
-
|
|
98
|
-
--skill {skill-root} --key workflow
|
|
78
|
+
uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --project-root {project-root} --key workflow
|
|
99
79
|
```
|
|
100
80
|
|
|
101
|
-
|
|
81
|
+
It merges the bundled `{skill-root}/customize.toml` with `{project-root}/_bmad/custom/skf-refine-architecture.toml` (team overrides, committed) and `.user.toml` (personal overrides, gitignored). When it exits non-zero, prints no JSON or is missing, print one line, `[activation/warn] customization_resolver_unavailable: <reason>` (`<reason>`: its first stderr line, `not found` when the script is missing, `no JSON` when it printed none). If the resolver cannot run, read `{skill-root}/customize.toml` alone and use its bundled defaults: the `{project-root}/_bmad/custom/` overrides do not apply to this run. In that case keep the reason as `{customization_resolver_unavailable}` for §5 to record.
|
|
102
82
|
|
|
103
|
-
|
|
104
|
-
- `_bmad/custom/<skill-name>.toml` under `{project-root}` — team overrides (committed)
|
|
105
|
-
- `_bmad/custom/<skill-name>.user.toml` under `{project-root}` — personal overrides (gitignored)
|
|
83
|
+
Bind each path scalar, taking the bundled default when the merged value is empty or absent:
|
|
106
84
|
|
|
107
|
-
|
|
85
|
+
- `{refinementRulesPath}` ← `workflow.refinement_rules_path` if non-empty, else `references/refinement-rules.md` (house style only: the file's first section names what a copy can change)
|
|
86
|
+
- `{outputFolderPath}` ← `workflow.output_folder_path` if non-empty, else `{output_folder}`
|
|
87
|
+
- `{onCompleteCommand}` ← `workflow.on_complete` if non-empty, else empty
|
|
108
88
|
|
|
109
|
-
|
|
89
|
+
Then run `workflow.activation_steps_prepend` now, treat `workflow.persistent_facts` as standing context for the run (`file:`-prefixed entries load their file/glob contents as facts: the bundled default loads every `project-context.md` under `{project-root}`; an entry prefixed `!` drops each earlier entry it names and loads nothing itself, so an override's `"!file:{project-root}/**/project-context.md"` turns that default off), then run `workflow.activation_steps_append` once §5's pre-flight has passed, before §6 loads the first stage.
|
|
110
90
|
|
|
111
|
-
|
|
112
|
-
- `{outputFolderPath}` ← `workflow.output_folder_path` if non-empty, else `{output_folder}`
|
|
113
|
-
- `{onCompleteCommand}` ← `workflow.on_complete` if non-empty, else empty (no-op — report.md skips the hook invocation entirely)
|
|
91
|
+
5. **Pre-flight: the emitter, config, write probe and run folder.** In that order, so every halt can print its envelope and an empty path halts as missing config (exit 3), not as a write failure.
|
|
114
92
|
|
|
115
|
-
|
|
93
|
+
**The emitter.** Resolve `{emitEnvelopeHelper}` ← `{project-root}/_bmad/skf/shared/scripts/skf-emit-result-envelope.py`, else `{project-root}/src/shared/scripts/skf-emit-result-envelope.py` (the first that exists). If neither exists, HALT (exit code 3, `halt_reason: "resolution-failure"`) at phase `on-activation:emitter` and display only: "Refine Architecture cannot run without `skf-emit-result-envelope.py`, which is not installed. Re-install SKF."
|
|
116
94
|
|
|
117
|
-
|
|
95
|
+
The halts below come before the run folder, so in headless mode each passes its payload on stdin, with `"customization_resolver_unavailable": "<reason>"` added when step 4 kept one:
|
|
118
96
|
|
|
119
|
-
|
|
97
|
+
```bash
|
|
98
|
+
uv run {emitEnvelopeHelper} emit-halt --workflow skf-refine-architecture --target stderr <<'SKF_RA_HALT'
|
|
99
|
+
{"phase": "<phase>", "reason": "<the halt message>", "halt_reason": "<halt_reason>"}
|
|
100
|
+
SKF_RA_HALT
|
|
101
|
+
```
|
|
120
102
|
|
|
121
|
-
**Config-completeness (exit 3).** If `{outputFolderPath}` is empty: HALT (exit code 3, `halt_reason: "output-folder-unconfigured"`)
|
|
103
|
+
**Config-completeness (exit 3).** If `{outputFolderPath}` is empty: HALT (exit code 3, `halt_reason: "output-folder-unconfigured"`) at phase `on-activation:config`: "Set `output_folder` in config.yaml, then re-run [RA]." If `{forge_data_folder}` is empty: HALT (exit code 3, `halt_reason: "forge-folder-unconfigured"`) at phase `on-activation:config`: "Set `forge_data_folder` in config.yaml, then re-run [RA]."
|
|
122
104
|
|
|
123
|
-
**Write probe (exit 4).**
|
|
105
|
+
**Write probe (exit 4).** Check that both paths are writable before any prompt:
|
|
124
106
|
|
|
125
107
|
```bash
|
|
126
108
|
for dir in "{outputFolderPath}" "{forge_data_folder}"; do
|
|
@@ -130,6 +112,14 @@ SKF_REFINE_ARCHITECTURE_RESULT_JSON: {"status":"success|error","refined_path":"
|
|
|
130
112
|
done
|
|
131
113
|
```
|
|
132
114
|
|
|
133
|
-
On any non-zero exit: HALT (exit code 4, `halt_reason: "write-failed"`)
|
|
115
|
+
On any non-zero exit: HALT (exit code 4, `halt_reason: "write-failed"`) at phase `on-activation:write-probe`, with `"path"` set to the folder that failed.
|
|
116
|
+
|
|
117
|
+
**Run folder (exit 4).** Create the run folder:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
mkdir -p "{project-root}/_bmad-output/.skf-run" && mkdir "{run_dir}"
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
If the command fails, HALT (exit code 4, `halt_reason: "write-failed"`) at phase `on-activation:run-folder`: "Cannot create the run folder `{run_dir}`: {the first stderr line}." Once it exists and `{customization_resolver_unavailable}` is set, record the reason in the run sink: write `customization_resolver_unavailable: {customization_resolver_unavailable}` to `{run_dir}/resolver-warning.txt` with a file write, never `echo`, then run `uv run {emitEnvelopeHelper} record --run-dir "{run_dir}" --warning "$(cat "{run_dir}/resolver-warning.txt")"`.
|
|
134
124
|
|
|
135
125
|
6. Load, read the full file, and then execute `references/init.md` to begin the workflow.
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
# DO NOT EDIT -- overwritten on every update.
|
|
2
2
|
#
|
|
3
3
|
# Workflow customization surface for skf-refine-architecture.
|
|
4
|
-
# Team overrides: _bmad/custom/skf-refine-architecture.toml
|
|
5
|
-
# Personal overrides: _bmad/custom/skf-refine-architecture.user.toml
|
|
4
|
+
# Team overrides: {project-root}/_bmad/custom/skf-refine-architecture.toml
|
|
5
|
+
# Personal overrides: {project-root}/_bmad/custom/skf-refine-architecture.user.toml
|
|
6
|
+
# The overrides apply only when BMad core's customization resolver runs;
|
|
7
|
+
# otherwise the run warns `customization_resolver_unavailable` and uses the
|
|
8
|
+
# defaults in this file.
|
|
6
9
|
|
|
7
10
|
[workflow]
|
|
8
11
|
|
|
@@ -10,27 +13,34 @@
|
|
|
10
13
|
# scalars: override wins • arrays (persistent_facts, activation_steps_*): append
|
|
11
14
|
# arrays-of-tables with `code`/`id`: replace matching items, append new ones.
|
|
12
15
|
|
|
13
|
-
# Steps to run
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
+
# Steps to run during activation, after the config load and the headless
|
|
17
|
+
# check and before the pre-flight (the emitter, the configured folders, the
|
|
18
|
+
# write probe and the run folder). Overrides append. Use for org-wide checks
|
|
19
|
+
# (auth, network, compliance) that must precede architecture refinement work.
|
|
16
20
|
|
|
17
21
|
activation_steps_prepend = []
|
|
18
22
|
|
|
19
|
-
# Steps to run
|
|
20
|
-
# Overrides append. Use for context loads or banner customization
|
|
21
|
-
# should run once activation completes successfully.
|
|
23
|
+
# Steps to run once the pre-flight has passed, before step 1 loads the
|
|
24
|
+
# inputs. Overrides append. Use for context loads or banner customization
|
|
25
|
+
# that should run once activation completes successfully.
|
|
22
26
|
|
|
23
27
|
activation_steps_append = []
|
|
24
28
|
|
|
25
29
|
# Persistent facts the workflow keeps in mind for the whole run
|
|
26
|
-
# (refinement standards, evidence-citation rules
|
|
27
|
-
# guardrails). Overrides append.
|
|
30
|
+
# (refinement standards, evidence-citation rules). Overrides append.
|
|
28
31
|
#
|
|
29
|
-
# Each entry is
|
|
32
|
+
# Each entry is one of:
|
|
30
33
|
# - a literal sentence, e.g. "Refinements must cite specific API signatures, never speculate."
|
|
31
34
|
# - a file reference prefixed with `file:`, e.g.
|
|
32
35
|
# "file:{project-root}/docs/refine-policy.md" (globs supported; file
|
|
33
36
|
# contents are loaded and treated as facts).
|
|
37
|
+
# - an entry prefixed with `!`, which loads nothing and drops each earlier
|
|
38
|
+
# entry it names.
|
|
39
|
+
#
|
|
40
|
+
# The default below loads every project-context.md under {project-root}.
|
|
41
|
+
# Overrides append, so they cannot delete it; to stop loading those files,
|
|
42
|
+
# set in {project-root}/_bmad/custom/skf-refine-architecture.toml:
|
|
43
|
+
# persistent_facts = ["!file:{project-root}/**/project-context.md"]
|
|
34
44
|
|
|
35
45
|
persistent_facts = [
|
|
36
46
|
"file:{project-root}/**/project-context.md",
|
|
@@ -38,21 +48,40 @@ persistent_facts = [
|
|
|
38
48
|
|
|
39
49
|
# --- Optional asset overrides ---
|
|
40
50
|
#
|
|
41
|
-
#
|
|
42
|
-
# rules
|
|
43
|
-
#
|
|
51
|
+
# House-style refinement rules. Empty = the bundled
|
|
52
|
+
# references/refinement-rules.md. A copy replaces that whole file, so start
|
|
53
|
+
# it from the bundled one: it can add, rename, drop or redefine the gap,
|
|
54
|
+
# issue and improvement types, name its own severity and value tiers, and
|
|
55
|
+
# decide which tier each [VS] verdict raises. It keeps the six tables the
|
|
56
|
+
# steps read by name, and each tier becomes a {<tier>_count} of the
|
|
57
|
+
# Refinement Summary, so step 1 halts on a copy that lacks a table or whose
|
|
58
|
+
# tiers break these rules: a tier name starts with a letter and holds only
|
|
59
|
+
# the letters A to Z, digits and spaces; no two tiers share a name (ignoring
|
|
60
|
+
# case), severity and value tiers included; none is named gap, issue,
|
|
61
|
+
# improvement, unverified or skill; and each VS Report Integration row
|
|
62
|
+
# raises a tier of Issue Severity, or no issue, not both (bold the one it
|
|
63
|
+
# raises). Fixed whatever the copy says: what each step looks for, which
|
|
64
|
+
# skills and pairs are analyzed (the document scope), how findings are
|
|
65
|
+
# stored for recovery (references/finding-storage.md), and how the refined
|
|
66
|
+
# document is built, marked and checked (headings, callouts, RA markers,
|
|
67
|
+
# preservation).
|
|
44
68
|
|
|
45
69
|
refinement_rules_path = ""
|
|
46
70
|
|
|
47
|
-
# Override the destination directory for the refined architecture document
|
|
48
|
-
#
|
|
71
|
+
# Override the destination directory for the refined architecture document
|
|
72
|
+
# and the files beside it: the earlier refined document a promotion renames,
|
|
73
|
+
# the result files (refine-architecture-result-<YYYYMMDD-HHmmss>.json and its
|
|
74
|
+
# -latest.json copy, the stable path pipelines read) and the record of
|
|
75
|
+
# findings a review dropped (.ra-dismissed-<project>.json). Empty = use
|
|
76
|
+
# {output_folder} from config.yaml. Useful for orgs that want
|
|
49
77
|
# refined-architecture artifacts to land under a curated docs tree.
|
|
50
78
|
|
|
51
79
|
output_folder_path = ""
|
|
52
80
|
|
|
53
|
-
# Optional post-completion hook. When non-empty,
|
|
54
|
-
# `--result-path=<path>`
|
|
55
|
-
#
|
|
56
|
-
#
|
|
81
|
+
# Optional post-completion hook: a shell command. When non-empty, step 6 runs
|
|
82
|
+
# it with `--result-path=<path>` (the per-run result JSON) once the refined
|
|
83
|
+
# architecture is promoted and both result files are written, before the run
|
|
84
|
+
# finishes. Use to index the refined doc, notify, or chain the next workflow.
|
|
85
|
+
# A failure shows as a warning line in step 6's report but never fails the run.
|
|
57
86
|
|
|
58
87
|
on_complete = ""
|
|
@@ -1,7 +1,21 @@
|
|
|
1
1
|
---
|
|
2
2
|
nextStepFile: 'report.md'
|
|
3
|
-
|
|
3
|
+
refinementRulesData: '{refinementRulesPath}'
|
|
4
4
|
outputFile: '{outputFolderPath}/refined-architecture-{arch_project_name}.md'
|
|
5
|
+
draftFile: '{forge_data_folder}/.skf-ra-draft-{project_name}.md'
|
|
6
|
+
planFile: '{run_dir}/insertion-plan.json'
|
|
7
|
+
applyResult: '{run_dir}/apply.json'
|
|
8
|
+
promoteResult: '{run_dir}/promote.json'
|
|
9
|
+
preservationScript: 'scripts/skf-check-preservation.py'
|
|
10
|
+
# The findings a review dropped (findingStorageData says how §8 records them).
|
|
11
|
+
dismissedFile: '{outputFolderPath}/.ra-dismissed-{arch_project_name}.json'
|
|
12
|
+
findingStorageData: 'references/finding-storage.md'
|
|
13
|
+
atomicWriteProbeOrder:
|
|
14
|
+
- '{project-root}/_bmad/skf/shared/scripts/skf-atomic-write.py'
|
|
15
|
+
- '{project-root}/src/shared/scripts/skf-atomic-write.py'
|
|
16
|
+
emitEnvelopeProbeOrder:
|
|
17
|
+
- '{project-root}/_bmad/skf/shared/scripts/skf-emit-result-envelope.py'
|
|
18
|
+
- '{project-root}/src/shared/scripts/skf-emit-result-envelope.py'
|
|
5
19
|
---
|
|
6
20
|
|
|
7
21
|
<!-- Config: communicate in {communication_language}. Compile the refined architecture document in {document_output_language}. -->
|
|
@@ -10,31 +24,39 @@ outputFile: '{outputFolderPath}/refined-architecture-{arch_project_name}.md'
|
|
|
10
24
|
|
|
11
25
|
## STEP GOAL:
|
|
12
26
|
|
|
13
|
-
|
|
27
|
+
Stage every finding of Steps 02-04 as an entry of an insertion plan, let the preservation script build the refined document from it as a draft, and present the draft for review; only the review's [C] replaces `{outputFile}`.
|
|
14
28
|
|
|
15
29
|
## Rules
|
|
16
30
|
|
|
17
|
-
- Do not discover new gaps, issues, or improvements
|
|
18
|
-
-
|
|
19
|
-
- Present compiled document for user review (gate checkpoint)
|
|
31
|
+
- Do not discover new gaps, issues, or improvements: use only what Steps 02-04 produced
|
|
32
|
+
- Never write the refined document yourself and never retype the original: `{preservationScript}` copies it, places the plan's blocks, checks that every original line survived and writes the draft
|
|
20
33
|
|
|
21
34
|
## MANDATORY SEQUENCE
|
|
22
35
|
|
|
36
|
+
**Halt envelope.** Every HALT in this step names its exit code, `halt_reason` and phase. In headless mode, stage `{run_dir}/halt.json` as `{"phase": "<phase>", "reason": "<the halt message>", "halt_reason": "<halt_reason>"}`, adding `"path"` when the halt names one, resolve `{emitEnvelopeHelper}` from `{emitEnvelopeProbeOrder}` if it is not bound (first existing path wins), then run:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
uv run {emitEnvelopeHelper} emit-halt --workflow skf-refine-architecture --run-dir "{run_dir}" --target stderr < "{run_dir}/halt.json"
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Display the line it prints, then stop with the halt's exit code (`references/exit-codes.md` describes the envelope). If no candidate exists, or the emitter exits non-zero or prints no line, display the halt message alone. An interactive HALT displays its message and emits nothing.
|
|
43
|
+
|
|
23
44
|
### 1. Prepare the Original as Base
|
|
24
45
|
|
|
25
|
-
|
|
46
|
+
The base is `{architecture_doc}` with any earlier Refine Architecture pass set aside, as Step 01 §1b set it aside in `{analysis_doc}`. §6's script reads `{architecture_doc}` itself; read `{analysis_doc}` only to pick each finding's anchor.
|
|
26
47
|
|
|
27
|
-
|
|
48
|
+
**Context recovery check:** read what is no longer in context from the RA state file: `{run_dir}`, `{timestamp}`, `{architecture_doc}` and `{arch_project_name}` from the `<!-- [RA-RUN] -->` block of `{forge_data_folder}/ra-state-{project_name}.md` (`{analysis_doc}` is `{run_dir}/analysis-doc.md`); the findings of Steps 02-04 from its `<!-- [RA-GAPS] -->`, `<!-- [RA-ISSUES] -->` and `<!-- [RA-IMPROVEMENTS] -->` blocks, and from `<!-- [RA-DISMISSED] -->` when there is one; `{unverified_technologies}` (Step 02 §2b), which the plan (§6) needs: the `<!-- [RA-SCOPE] -->` block; `{vs_report}`, which the VS Coverage row (§5) needs: the `<!-- [RA-VS] -->` block (its `path`, `generatedAt`, `coveragePercentage` and `coverageMeasured`, or `none`). When a block is still missing, or a findings block holds only summary counts, HALT (exit code 8, `halt_reason: "recovery-failed"`) at phase `compile:recovery`: "⚠️ Context for the [Gaps|Issues|Improvements|Scope|VS report] analysis was lost and the state file cannot rebuild it. Re-run [RA] from the beginning: step 01 resets the state file and steps 02-04 rebuild every finding."
|
|
28
49
|
|
|
29
|
-
|
|
50
|
+
### 2. Plan the Gap-Fill Subsections
|
|
30
51
|
|
|
31
|
-
|
|
52
|
+
The insertion plan is one JSON object, written to `{planFile}` at §6 (the script's module docstring gives every field). Each finding becomes one entry of its `entries` list: an `id` (`gap-1`, `issue-1`, `improvement-1` and so on), its `kind` (`gap`, `issue` or `improvement`), the `anchor` that places it, the `skills` its evidence cites, and the `block` to insert. A finding stored under `[RA-DISMISSED]` gets no entry: §7 lists it, and §8 gives it one only when the user takes it back.
|
|
32
53
|
|
|
33
|
-
|
|
54
|
+
**Anchors.** An anchor is text copied exactly from one line of `{analysis_doc}`: a heading line such as `## Data Layer`, or the sentence a finding is about. It must occur on exactly one line (a heading anchor matches only a heading of its level and title); when several lines hold it, add `occurrence` (1-based) to pick one. An anchor of `null` sends the entry to its kind's fallback section at the end of the document.
|
|
34
55
|
|
|
35
|
-
|
|
56
|
+
For each gap finding from Step 02:
|
|
36
57
|
|
|
37
|
-
**
|
|
58
|
+
- **anchor:** the heading of the section where this integration logically belongs. The script puts the block at the end of that section, one heading level deeper. `null` when no section fits: the script then collects the gap under `## RA: Additional Integration Paths`.
|
|
59
|
+
- **block** (the script sets the heading's level, so any number of `#` will do):
|
|
38
60
|
|
|
39
61
|
```markdown
|
|
40
62
|
#### RA: {Library A} <-> {Library B} Integration Path
|
|
@@ -48,15 +70,12 @@ For each gap finding from Step 02:
|
|
|
48
70
|
{Suggested architecture content describing how the libraries connect}
|
|
49
71
|
```
|
|
50
72
|
|
|
51
|
-
|
|
73
|
+
### 3. Plan the Issue Annotations
|
|
52
74
|
|
|
53
|
-
|
|
75
|
+
For each issue finding from Step 03, with `tier` its severity, a tier of the Issue Severity table of `{refinementRulesData}`:
|
|
54
76
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
**Locate the section** containing the contradicted claim.
|
|
58
|
-
|
|
59
|
-
**Insert an issue callout block** immediately after the contradicted text:
|
|
77
|
+
- **anchor:** the contradicted claim, exactly as Step 03 recorded it from its line of `{analysis_doc}`. The script puts the callout right after the block (paragraph, list, table, blockquote or code fence) that holds the claim. `null` when the claim cannot be located precisely: the script collects such issues under `## RA: Additional Issues Detected`, the most severe tier first.
|
|
78
|
+
- **block:**
|
|
60
79
|
|
|
61
80
|
```markdown
|
|
62
81
|
> [!WARNING] **Issue Detected by Refine Architecture** ({severity})
|
|
@@ -67,18 +86,15 @@ For each issue finding from Step 03:
|
|
|
67
86
|
> **Suggested Correction:** {specific correction with API evidence}
|
|
68
87
|
```
|
|
69
88
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
### 4. Insert Improvement Suggestions
|
|
89
|
+
### 4. Plan the Improvement Suggestions
|
|
73
90
|
|
|
74
|
-
For each improvement finding from Step 04
|
|
91
|
+
For each in-scope improvement finding from Step 04 (the `[RA-IMPROVEMENTS]` findings; out-of-scope improvements and synergies stay under `[RA-OUT-OF-SCOPE]` and never enter the refined document), with `tier` its value, a tier of the Improvement Value table of `{refinementRulesData}`:
|
|
75
92
|
|
|
76
|
-
**
|
|
77
|
-
|
|
78
|
-
**Insert an improvement subsection** one heading level deeper:
|
|
93
|
+
- **anchor:** the heading of the section where the library is discussed, also when it appears there only in a table, code block or Mermaid diagram: the script puts the block at the end of that section, one heading level deeper. `null` when no section discusses the library: the script then collects the improvement under `## RA: Additional Improvements Suggested`, the most valuable tier first.
|
|
94
|
+
- **block:**
|
|
79
95
|
|
|
80
96
|
```markdown
|
|
81
|
-
#### RA: Enhancement
|
|
97
|
+
#### RA: Enhancement: {Improvement Title}
|
|
82
98
|
|
|
83
99
|
> [!TIP] **Improvement Suggested by Refine Architecture** ({value} value)
|
|
84
100
|
> {skill_name} provides `{api}` which is not currently leveraged.
|
|
@@ -89,63 +105,90 @@ For each improvement finding from Step 04:
|
|
|
89
105
|
{Specific suggestion for updating the architecture}
|
|
90
106
|
```
|
|
91
107
|
|
|
92
|
-
**Order by value:** High value improvements first, then Medium, then Low.
|
|
93
|
-
|
|
94
|
-
**Placement fallback:** If the library's only architecture mention is inside a table, code block, or Mermaid diagram where inserting a subsection would break syntax, collect into `## RA: Additional Improvements Suggested` at the end of the document.
|
|
95
|
-
|
|
96
108
|
### 5. Add Refinement Summary Section
|
|
97
109
|
|
|
98
|
-
|
|
110
|
+
The plan's `summary` is the `## Refinement Summary` section, which the script appends last. Leave the count placeholders below as they are: the script fills `{gap_count}`, `{issue_count}`, `{improvement_count}`, a `{<tier>_count}` for each severity and value tier and `{evidence_rows}` from the plan's entries, `{unverified_count}` and `{unverified_technologies}` from its `unverified_technologies`, and `{skill_count}`, and it refuses a summary that types the three totals or holds a placeholder it does not know. Fill the others yourself. The section contains:
|
|
99
111
|
|
|
100
112
|
- **Header:** "Produced by: Refine Architecture workflow using {skill_count} skills" and date
|
|
101
|
-
- **Changes Made table
|
|
113
|
+
- **Changes Made table**, whose Issues Flagged and Improvements Suggested breakdowns name each tier of `{rule_tiers}` (its `issue`, then its `improvement` list) in order, each as `<Tier>: {<tier>_count}`; the rows below show the bundled tiers:
|
|
102
114
|
|
|
103
115
|
| Category | Count | Breakdown |
|
|
104
116
|
|----------|-------|-----------|
|
|
105
|
-
| Gaps Filled | {gap_count} |
|
|
117
|
+
| Gaps Filled | {gap_count} | - |
|
|
106
118
|
| Issues Flagged | {issue_count} | Critical: {critical_count}, Major: {major_count}, Minor: {minor_count} |
|
|
107
119
|
| Improvements Suggested | {improvement_count} | High: {high_count}, Medium: {medium_count}, Low: {low_count} |
|
|
108
|
-
| Skills Used as Evidence | {skill_count} |
|
|
109
|
-
|
|
110
|
-
|
|
120
|
+
| Skills Used as Evidence | {skill_count} | - |
|
|
121
|
+
| Not verified (no skill) | {unverified_count} | {unverified_technologies} |
|
|
122
|
+
| VS Coverage | {vs_coverage} | technologies with a skill when [VS] ran, from `{vs_report_name}` |
|
|
123
|
+
|
|
124
|
+
The Not verified (no skill) row is always written: its Breakdown names the technologies comma-separated, or reads `none`. Write the VS Coverage row only when a VS report was used (`vs_report_available` is true), from the report JSON Step 01 §1 cached (`{vs_report}`), never from the report file: `{vs_coverage}` is its `coveragePercentage` followed by `%` when its `coverageMeasured` is true, and `not recorded` when `coverageMeasured` is false. `{vs_report_name}` is the file name of the JSON's `path`: the refined document is shared, so it names no folder.
|
|
125
|
+
|
|
126
|
+
- **Evidence Sources table:** a `| Skill | Refinements |` header row and its separator, then `{evidence_rows}` (the script writes one row per cited skill)
|
|
127
|
+
- **Next Steps:** Review `[!WARNING]` issues, `[!NOTE]` gaps, `[!TIP]` improvements; then run **[SS] Stack Skill** to compose your individual skills into a unified stack skill, providing this refined architecture doc when prompted. When `{unverified_technologies}` is not empty, add one line before [SS] that names them: nothing checked what the architecture says about them, so generate their skills with **[CS] Create Skill** or **[QS] Quick Skill** and re-run **[RA]** first.
|
|
111
128
|
|
|
112
|
-
### 6.
|
|
129
|
+
### 6. Build the Draft
|
|
130
|
+
|
|
131
|
+
Write the plan to `{planFile}`: the `entries` of §2 to §4, the `summary` of §5, `unverified_technologies` (Step 02 §2b's list as written in the document, `[]` when it is empty), `skill_count` (the inventory's `{skill_count}`, Step 01 §2) and `tiers` (`{"issue": [...], "improvement": [...]}`: `{rule_tiers}`, the `tiers` Step 01 §4's `rules` check printed; run that command again if they are no longer in context). Then run:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
uv run {preservationScript} apply --original "{architecture_doc}" --plan "{planFile}" --draft "{draftFile}" -o "{applyResult}"
|
|
135
|
+
```
|
|
113
136
|
|
|
114
|
-
|
|
137
|
+
Branch on its exit code:
|
|
115
138
|
|
|
116
|
-
|
|
139
|
+
- **0:** the draft is written and the check passed. `{applyResult}` holds its `counts`, `evidence`, filled `summary`, `unverified_technologies` and `set_aside` (the earlier pass's blocks), where §7 and Step 06 take every number and name.
|
|
140
|
+
- **1 with `status: "problems"`:** nothing was written. Each entry of `problems[]` names the plan entry (`id`), the `reason` and what to change (an anchor's `closest` line or its `matches`, of which `occurrence` can pick one). Fix the plan and run the command again; an anchor still not found after one fix becomes `null`.
|
|
141
|
+
- **1 with `status: "not-preserved"`:** the draft would lose or change a line of the original, so nothing was written (an earlier draft stays as it was), and running the same plan again gives the same result. Show the first entry of `missing[]` and of `altered[]`. In headless, HALT (exit code 4, `halt_reason: "preservation-failed"`) at phase `compile:draft` without a retry, naming that first line; in an interactive run, show the failure at §7 and offer no [C] until a feedback round's `apply` passes.
|
|
142
|
+
- **2** with a JSON (`error` names the file it could not read): for `{planFile}`, write the plan again; for `{architecture_doc}`, HALT (exit code 2, `halt_reason: "input-invalid"`) at phase `compile:draft`, with `"path"` set to it. **2 with no JSON:** a malformed call: fix it and run it again.
|
|
143
|
+
- **3:** the draft could not be written: HALT (exit code 4, `halt_reason: "write-failed"`) at phase `compile:draft`, naming its `error`, with `"path": "{draftFile}"`.
|
|
144
|
+
- If `uv` cannot start the script, here or for §8's `promote`: HALT (exit code 3, `halt_reason: "resolution-failure"`) at phase `compile:draft` (`compile:promote` for `promote`).
|
|
117
145
|
|
|
118
|
-
|
|
146
|
+
`{outputFile}` is not touched here: an earlier refined document stays as it is until §8's [C].
|
|
147
|
+
|
|
148
|
+
### 7. Present the Draft for Review
|
|
119
149
|
|
|
120
150
|
"**Refined architecture compiled. Please review:**
|
|
121
151
|
|
|
122
152
|
---
|
|
123
153
|
|
|
124
|
-
{Display the
|
|
154
|
+
{Display the `summary` of `{applyResult}`: the Refinement Summary as the draft holds it}
|
|
125
155
|
|
|
126
156
|
---
|
|
127
157
|
|
|
128
|
-
**
|
|
158
|
+
{IF the `[RA-DISMISSED]` block holds findings:}**Left out, as a review dropped them from an earlier refinement of this document.** Ask for one back to insert it:
|
|
159
|
+
{One line per finding: its kind, its skills, its own title and the title of the record it matched}
|
|
160
|
+
|
|
161
|
+
**The draft is at:** `{draftFile}`. {IF `{outputFile}` exists: `{outputFile}` still holds your earlier refined document; approving renames it with this run's timestamp before the draft takes its place.}{ELSE: Approving writes it to `{outputFile}`.} Ask for changes here rather than editing the draft: each feedback round rebuilds it.
|
|
129
162
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
- {issue_count} issue annotations inserted
|
|
133
|
-
- {improvement_count} improvement suggestions included
|
|
134
|
-
- Original architecture content preserved in full
|
|
163
|
+
- {IF the last `apply` failed the check:}The draft would lose or change line {the first `missing[]` or `altered[]` line} of the original: [C] waits for a draft that passes{ELSE IF its `set_aside` holds a `legacy` entry:}Every original line is preserved except lines {ranges} of `{architecture_doc}` (each `legacy` entry's `start`-`end`), which an earlier pass left without RA markers: they were set aside unchecked, so text of your own there is not in the draft{ELSE:}Original architecture content preserved in full: the preservation script found every line unchanged{END IF}
|
|
164
|
+
{IF previous_pass:}- The earlier Refine Architecture pass in this document was set aside, and these refinements replace it
|
|
135
165
|
|
|
136
|
-
**Does the refinement look correct?**"
|
|
166
|
+
**Does the refinement look correct?** Choose [R] to walk through each refinement with its evidence, or tell me what to change, such as a finding to drop."
|
|
137
167
|
|
|
138
168
|
### 8. Present MENU OPTIONS
|
|
139
169
|
|
|
140
|
-
Display: **Select:** [C]
|
|
170
|
+
Display: **Select:** [R] Review each refinement | [C] Approve and replace the refined document | [X] Cancel
|
|
141
171
|
|
|
142
172
|
#### GATE [default: C]
|
|
143
173
|
|
|
144
|
-
|
|
174
|
+
Wait for the user's choice. Headless auto-selects [C] (log: "headless: auto-approve compiled architecture") and records that decision in the run sink the moment it is taken: stage `{run_dir}/decision.json` as `{"gate": "compile.review", "default_action": "C", "taken_action": "C", "reason": "headless: auto-approve compiled architecture", "evidence": {"draft": "{draftFile}", "output": "{outputFile}"}}`, then run:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
uv run {emitEnvelopeHelper} record --workflow skf-refine-architecture --run-dir "{run_dir}" --decision < "{run_dir}/decision.json"
|
|
178
|
+
```
|
|
145
179
|
|
|
146
180
|
#### Menu Handling Logic:
|
|
147
181
|
|
|
148
|
-
- IF
|
|
149
|
-
- IF
|
|
150
|
-
|
|
182
|
+
- IF R: walk through each refinement with its evidence and its plan `id`, so feedback can name it: the gaps, the issues by severity, the improvements by value, then the findings left out as previously dismissed. It changes nothing; then redisplay this menu.
|
|
183
|
+
- IF C (only while the last `apply` exited 0): promote the draft. The script checks it once more, renames a file already at `{outputFile}` to `refined-architecture-{arch_project_name}-{timestamp}.md` (or a free `-2` name), and moves the draft there:
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
uv run {preservationScript} promote --original "{architecture_doc}" --draft "{draftFile}" --output "{outputFile}" --timestamp "{timestamp}" -o "{promoteResult}"
|
|
187
|
+
```
|
|
151
188
|
|
|
189
|
+
- **0:** the draft is now `{outputFile}`, and `{promoteResult}` records `previous`, the name the earlier refined document took (null when there was none). When a feedback round staged `{run_dir}/dismissed.json`, only now write it to `{dismissedFile}`, as `{findingStorageData}` says. Then load, read the entire file, and execute `{nextStepFile}`.
|
|
190
|
+
- **1** (`not-preserved`): nothing was moved. Show the first entry of `missing[]` or `altered[]`, rebuild once with §6's `apply`, and promote again. If it fails the same way, HALT (exit code 4, `halt_reason: "preservation-failed"`) at phase `compile:promote`, naming that line: the draft stays at `{draftFile}` and `{outputFile}` is as it was.
|
|
191
|
+
- **2** with a JSON (`error` names the file it could not read): for the draft, rebuild it once and promote again, and if it still cannot be read, HALT (exit code 4, `halt_reason: "write-failed"`) at phase `compile:promote`, with `"path": "{draftFile}"`; for `{architecture_doc}`, HALT (exit code 2, `halt_reason: "input-invalid"`) at phase `compile:promote`, with `"path"` set to it. **2 with no JSON:** fix the malformed call and run it again.
|
|
192
|
+
- **3:** HALT (exit code 4, `halt_reason: "write-failed"`) at phase `compile:promote`, naming its `error`, with `"path": "{outputFile}"`. `{outputFile}` is as it was unless the `error` names a file the script could not put back.
|
|
193
|
+
- IF cancel / exit / [X] / q / :q: delete the draft (`rm -f "{draftFile}"`), display "Cancelled: refinement not finalized. `{outputFile}` is unchanged." and HALT (exit code 6, `halt_reason: "user-cancelled"`) at phase `compile:review`. These global cancel tokens pre-empt the feedback branch below.
|
|
194
|
+
- IF Any other: process it as feedback on the plan: in `{planFile}`, change the anchor, tier or block of the entries it names, drop an entry the user rejects, or add one (as §2 to §4 would) for a dismissed finding the user takes back, and record each drop or take-back in `{run_dir}/dismissed.json` as `{findingStorageData}` says. Then run §6's `apply` again: it rebuilds the draft from the original, so feedback never edits the draft. On exit 0, redisplay §7; on a failure, handle it as §6 says (the previous draft stays), and [C] waits for a round whose `apply` passes. Then [Redisplay Menu Options](#8-present-menu-options)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Exit Codes and Result Envelope
|
|
2
|
+
|
|
3
|
+
Every hard halt in this workflow exits with a stable code so headless automators can branch on the failure class without grepping message text. Each code pairs with a `halt_reason` string carried in the headless result envelope.
|
|
4
|
+
|
|
5
|
+
| Code | Meaning | Raised by |
|
|
6
|
+
| ---- | -------------------- | -------------------------------------------------------------------------------------------- |
|
|
7
|
+
| 0 | success | step 7 (terminal) |
|
|
8
|
+
| 2 | input-missing / input-invalid | step 1 §1 (headless with no `--architecture-doc`) → `input-missing`; step 1 §1 (an architecture document that is missing or unreadable, or a [VS] report that breaks the feasibility-report contract (`schemaVersion` not `1.0`, a section missing or out of order, a missing or second verdict table, an unknown verdict token) or cannot be read), step 1 §1b and step 5 §6 and §8 (the architecture document cannot be read as UTF-8 text) → `input-invalid` |
|
|
9
|
+
| 3 | resolution-failure | On Activation §5 (`output_folder` or `forge_data_folder` unconfigured → `output-folder-unconfigured` / `forge-folder-unconfigured`; the result emitter is not installed → `resolution-failure`); a helper is not installed, cannot start or fails: step 1 §2 (`skf-enumerate-stack-skills.py`, phase `init:inventory`), step 2 §2 (`skf-comention-pairs.py`, phase `gap-analysis:comention`); a helper is not installed or `uv` cannot start it: step 1 §1 (`skf-validate-feasibility-report.py`, phase `init:feasibility-validator`), step 1 §1b, step 3 §4, step 5 §6 and §8 and step 6 §1 (`scripts/skf-check-preservation.py`, or at step 3 §4 the shared feasibility-report reader it runs) → `resolution-failure`; step 1 §4 (the refinement rules cannot be read, lack a table the steps read or name a tier the Refinement Summary cannot count) → `resolution-failure` |
|
|
10
|
+
| 4 | write-failure | On Activation §5 (the write probe, the run folder); step 1 §1b (the analysis copy); step 1 §3c (the RA state file); step 5 §6 (the draft) and §8 (the promotion, or a draft that still cannot be read after one rebuild); step 6 §1 (the result payload) and §4 (the emitter refuses it twice) → `write-failed`; step 5 §6 (in headless, the draft would lose or change a line of the original) and §8 (it still would after one rebuild) → `preservation-failed` |
|
|
11
|
+
| 5 | state-conflict | step 1 §3 (no skill SKF generated was found: refinement requires ≥1 skill) → `insufficient-skills` |
|
|
12
|
+
| 6 | user-cancelled | step 1 §1 prompt cancelled; step 2 §2b scope confirmation `[X]`; any prompt that accepted `cancel`/`exit`/`:q`; step 5 review gate `[X]` (the draft is deleted, `{outputFile}` is unchanged) |
|
|
13
|
+
| 7 | inventory-unreliable | step 1 §2 (skill-inventory warnings exceed the failure budget); skills SKF did not generate are not counted |
|
|
14
|
+
| 8 | recovery-failed | step 3 §4 (the [VS] report cannot be read again, or [VS] rewrote it during the run, or the refinement rules no longer pass step 1's check); step 5 §1 (the saved state is not enough to rebuild the Step 02-04 findings, the scope or the VS report); step 6 §1 (a record of the draft's build or promotion is missing) |
|
|
15
|
+
|
|
16
|
+
## Result Envelope
|
|
17
|
+
|
|
18
|
+
When `{headless_mode}` is true, step 6 prints one `SKF_REFINE_ARCHITECTURE_RESULT_JSON: {...}` line on **stdout** when it writes the result contract, and every HARD HALT prints one on **stderr** with `status: "error"`. The shared emitter builds each line from the payload the stage stages in `{run_dir}`, folds in the decisions and warnings the run recorded there, and checks it against `{project-root}/_bmad/skf/shared/scripts/schemas/skf-refine-architecture-result-envelope.v1.json` (`{project-root}/src/shared/scripts/schemas/skf-refine-architecture-result-envelope.v1.json` in a dev checkout), whose descriptions say what each field holds: `status`, `refined_path`, `previous_refined_path`, `previous_pass`, `gap_count`, `issue_count`, `improvement_count`, `unverified_count`, `exit_code`, `halt_reason`, `run_id`, `result_path`, and `headless_decisions`, `warnings` and `error` when they apply. Never type the line yourself.
|
|
19
|
+
|
|
20
|
+
`status` is `"success"` on the terminal happy path, `"error"` on any HALT. `halt_reason` is one of: `null` (success), `"input-missing"`, `"input-invalid"`, `"insufficient-skills"`, `"output-folder-unconfigured"`, `"forge-folder-unconfigured"`, `"resolution-failure"`, `"inventory-unreliable"`, `"write-failed"`, `"preservation-failed"`, `"recovery-failed"`, `"user-cancelled"`. `exit_code` matches the table above, and the emitter derives it from `halt_reason`.
|
|
21
|
+
|
|
22
|
+
## Emitting a Halt
|
|
23
|
+
|
|
24
|
+
Every HALT names its exit code, `halt_reason` and phase. In headless mode, stage `{run_dir}/halt.json` as `{"phase": "<phase>", "reason": "<the halt message>", "halt_reason": "<halt_reason>"}`, adding `"refined_path": "{outputFile}"` once step 5 promoted the draft and `"path"` when the halt names one, then run:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
uv run {emitEnvelopeHelper} emit-halt --workflow skf-refine-architecture --run-dir "{run_dir}" --target stderr < "{run_dir}/halt.json"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Each stage that halts shows this command and the probe order that resolves `{emitEnvelopeHelper}`, so a late halt emits the right line even when this file is not in context. Display the line it prints, then stop with the halt's exit code. If the emitter exits non-zero or prints no line, display the halt message alone. An interactive HALT displays its message and emits nothing. A HALT before the run folder exists (SKILL.md On Activation §5) passes the payload on stdin instead.
|