bmad-module-skill-forge 1.9.0 → 2.0.1
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/.nvmrc +1 -1
- package/README.md +10 -5
- package/docs/_data/pinned.yaml +2 -2
- package/docs/agents.md +11 -2
- package/docs/architecture.md +5 -4
- package/docs/bmad-synergy.md +30 -7
- package/docs/campaign.md +172 -0
- package/docs/examples.md +7 -3
- package/docs/forge-auto.md +90 -0
- package/docs/getting-started.md +9 -0
- package/docs/how-it-works.md +6 -4
- package/docs/index.md +4 -3
- package/docs/skill-model.md +1 -1
- package/docs/troubleshooting.md +17 -1
- package/docs/verifying-a-skill.md +2 -2
- package/docs/why-skf.md +1 -1
- package/docs/workflows.md +64 -24
- package/package.json +2 -2
- package/src/knowledge/skill-lifecycle.md +1 -1
- package/src/module-help.csv +4 -3
- package/src/shared/data/language-corpora.json +32 -0
- package/src/shared/references/pipeline-contracts.md +6 -3
- package/src/shared/scripts/schemas/skill-brief.v1.json +6 -1
- package/src/shared/scripts/skf-comention-pairs.py +350 -0
- package/src/shared/scripts/skf-count-tokens.py +222 -0
- package/src/shared/scripts/skf-derive-assembly-shape.py +107 -0
- package/src/shared/scripts/skf-detect-docs.py +240 -4
- package/src/shared/scripts/skf-detect-language.py +82 -3
- package/src/shared/scripts/skf-detect-tools.py +105 -2
- package/src/shared/scripts/skf-emit-result-envelope.py +17 -0
- package/src/shared/scripts/skf-enumerate-stack-skills.py +111 -2
- package/src/shared/scripts/skf-extract-public-api.py +53 -0
- package/src/shared/scripts/skf-find-cycles.py +246 -0
- package/src/shared/scripts/skf-hash-content.py +487 -2
- package/src/shared/scripts/skf-language-corpora.py +100 -0
- package/src/shared/scripts/skf-manifest-ops.py +67 -1
- package/src/shared/scripts/skf-merge-doc-urls.py +244 -0
- package/src/shared/scripts/skf-preapply.py +1 -1
- package/src/shared/scripts/skf-rebuild-managed-sections.py +180 -0
- package/src/shared/scripts/skf-recommend-scope-type.py +1 -2
- package/src/shared/scripts/skf-render-metadata-stats.py +499 -0
- package/src/shared/scripts/skf-rewrite-skill-name.py +308 -0
- package/src/shared/scripts/skf-shape-detect.py +576 -25
- package/src/shared/scripts/skf-shard-body.py +461 -0
- package/src/shared/scripts/skf-skill-inventory.py +139 -3
- package/src/shared/scripts/skf-structural-diff.py +307 -67
- package/src/shared/scripts/skf-validate-brief-schema.py +41 -6
- package/src/shared/scripts/skf-validate-feasibility-report.py +234 -0
- package/src/shared/scripts/skf-validate-frontmatter.py +17 -12
- package/src/shared/scripts/skf-validate-output.py +443 -10
- package/src/shared/scripts/skf-validate-pins.py +3 -3
- package/src/shared/scripts/skf-verify-no-trace.py +214 -0
- package/src/shared/scripts/skf-verify-provenance-completeness.py +439 -0
- package/src/shared/scripts/skf-write-skill-brief.py +21 -5
- package/src/skf-analyze-source/SKILL.md +17 -32
- package/src/skf-analyze-source/assets/skill-brief-schema.md +1 -1
- package/src/skf-analyze-source/customize.toml +2 -0
- package/src/skf-analyze-source/references/auto-docs-only.md +116 -0
- package/src/skf-analyze-source/references/continue.md +8 -13
- package/src/skf-analyze-source/references/generate-briefs.md +28 -12
- package/src/skf-analyze-source/references/headless-contract.md +33 -0
- package/src/skf-analyze-source/references/health-check.md +1 -2
- package/src/skf-analyze-source/references/identify-units.md +25 -36
- package/src/skf-analyze-source/references/init.md +12 -25
- package/src/skf-analyze-source/references/map-and-detect.md +8 -20
- package/src/skf-analyze-source/references/recommend.md +4 -14
- package/src/skf-analyze-source/references/scan-project.md +3 -11
- package/src/skf-analyze-source/references/step-auto-scope.md +211 -197
- package/src/skf-analyze-source/references/step-shape-detect.md +20 -13
- package/src/skf-analyze-source/references/unit-detection-heuristics.md +2 -2
- package/src/skf-audit-skill/SKILL.md +9 -6
- package/src/skf-audit-skill/customize.toml +2 -0
- package/src/skf-audit-skill/references/init.md +58 -32
- package/src/skf-audit-skill/references/re-index.md +15 -34
- package/src/skf-audit-skill/references/report.md +11 -58
- package/src/skf-audit-skill/references/semantic-diff.md +4 -22
- package/src/skf-audit-skill/references/severity-classify.md +53 -87
- package/src/skf-audit-skill/references/step-doc-drift.md +49 -19
- package/src/skf-audit-skill/references/structural-diff.md +43 -68
- package/src/skf-brief-skill/SKILL.md +7 -36
- package/src/skf-brief-skill/assets/scope-templates.md +1 -1
- package/src/skf-brief-skill/assets/skill-brief-schema.md +1 -1
- package/src/skf-brief-skill/customize.toml +14 -0
- package/src/skf-brief-skill/references/analyze-target.md +13 -18
- package/src/skf-brief-skill/references/confirm-brief.md +2 -15
- package/src/skf-brief-skill/references/draft-checkpoint.md +8 -8
- package/src/skf-brief-skill/references/gather-intent.md +27 -24
- package/src/skf-brief-skill/references/headless-args.md +1 -1
- package/src/skf-brief-skill/references/health-check.md +1 -22
- package/src/skf-brief-skill/references/invocation-contract.md +37 -0
- package/src/skf-brief-skill/references/scope-definition.md +6 -15
- package/src/skf-brief-skill/references/step-auto-brief.md +22 -9
- package/src/skf-brief-skill/references/step-auto-validate.md +3 -7
- package/src/skf-brief-skill/references/version-resolution.md +1 -1
- package/src/skf-brief-skill/references/write-brief.md +19 -13
- package/src/skf-campaign/SKILL.md +121 -0
- package/src/skf-campaign/assets/campaign-state-schema.json +191 -0
- package/src/skf-campaign/customize.toml +75 -0
- package/src/skf-campaign/manifest.yaml +15 -0
- package/src/skf-campaign/references/campaign-contracts.md +67 -0
- package/src/skf-campaign/references/campaign-directive-spec.md +32 -0
- package/src/skf-campaign/references/health-check.md +35 -0
- package/src/skf-campaign/references/step-01-setup.md +121 -0
- package/src/skf-campaign/references/step-02-strategy.md +102 -0
- package/src/skf-campaign/references/step-03-pins.md +56 -0
- package/src/skf-campaign/references/step-04-provenance.md +63 -0
- package/src/skf-campaign/references/step-05-skill-loop.md +103 -0
- package/src/skf-campaign/references/step-06-batch.md +88 -0
- package/src/skf-campaign/references/step-07-capstone.md +63 -0
- package/src/skf-campaign/references/step-08-verify.md +75 -0
- package/src/skf-campaign/references/step-09-refine.md +83 -0
- package/src/skf-campaign/references/step-10-export.md +106 -0
- package/src/skf-campaign/references/step-11-maintenance.md +84 -0
- package/src/skf-campaign/references/step-resume.md +115 -0
- package/src/skf-campaign/scripts/.gitkeep +0 -0
- package/src/skf-campaign/scripts/campaign-deps.py +244 -0
- package/src/skf-campaign/scripts/campaign-parse-manifest.py +119 -0
- package/src/skf-campaign/scripts/campaign-provenance.py +247 -0
- package/src/skf-campaign/scripts/campaign-render-batch.py +199 -0
- package/src/skf-campaign/scripts/campaign-render-kickoff.py +158 -0
- package/src/skf-campaign/scripts/campaign-report.py +249 -0
- package/src/skf-campaign/scripts/campaign-status.py +162 -0
- package/src/skf-campaign/scripts/campaign-validate-pins.py +174 -0
- package/src/skf-campaign/scripts/campaign-validate-state.py +207 -0
- package/src/skf-campaign/templates/campaign-brief-template.yaml +34 -0
- package/src/skf-campaign/templates/campaign-report-template.md +54 -0
- package/src/skf-campaign/templates/kickoff-template.md +48 -0
- package/src/skf-create-skill/SKILL.md +15 -4
- package/src/skf-create-skill/assets/compile-assembly-rules.md +35 -34
- package/src/skf-create-skill/assets/skill-sections.md +9 -100
- package/src/skf-create-skill/assets/tessl-dismissal-rules.md +4 -13
- package/src/skf-create-skill/customize.toml +13 -0
- package/src/skf-create-skill/references/authoritative-files-protocol.md +7 -7
- package/src/skf-create-skill/references/compile.md +37 -47
- package/src/skf-create-skill/references/component-extraction.md +8 -35
- package/src/skf-create-skill/references/ecosystem-check.md +9 -25
- package/src/skf-create-skill/references/enrich.md +4 -17
- package/src/skf-create-skill/references/extract.md +20 -27
- package/src/skf-create-skill/references/extraction-patterns-tracing.md +1 -1
- package/src/skf-create-skill/references/extraction-patterns.md +10 -8
- package/src/skf-create-skill/references/generate-artifacts.md +20 -25
- package/src/skf-create-skill/references/health-check.md +2 -2
- package/src/skf-create-skill/references/load-brief.md +16 -18
- package/src/skf-create-skill/references/report.md +27 -14
- package/src/skf-create-skill/references/source-resolution-protocols.md +4 -4
- package/src/skf-create-skill/references/step-auto-shard.md +52 -25
- package/src/skf-create-skill/references/step-doc-rot.md +33 -15
- package/src/skf-create-skill/references/step-doc-sources.md +13 -4
- package/src/skf-create-skill/references/sub/ccc-discover.md +2 -13
- package/src/skf-create-skill/references/sub/fetch-docs.md +33 -46
- package/src/skf-create-skill/references/sub/fetch-temporal.md +5 -20
- package/src/skf-create-skill/references/tier-degradation-rules.md +6 -8
- package/src/skf-create-skill/references/validate.md +69 -29
- package/src/skf-create-skill/scripts/scan-doc-rot.py +245 -0
- package/src/skf-create-stack-skill/SKILL.md +15 -9
- package/src/skf-create-stack-skill/assets/provenance-map-schema.md +1 -1
- package/src/skf-create-stack-skill/customize.toml +10 -0
- package/src/skf-create-stack-skill/references/compile-stack.md +7 -8
- package/src/skf-create-stack-skill/references/compose-mode-rules.md +2 -13
- package/src/skf-create-stack-skill/references/detect-integrations.md +49 -54
- package/src/skf-create-stack-skill/references/detect-manifests.md +37 -30
- package/src/skf-create-stack-skill/references/generate-output.md +24 -75
- package/src/skf-create-stack-skill/references/init.md +9 -81
- package/src/skf-create-stack-skill/references/manifest-patterns.md +5 -35
- package/src/skf-create-stack-skill/references/parallel-extract.md +12 -27
- package/src/skf-create-stack-skill/references/rank-and-confirm.md +6 -6
- package/src/skf-create-stack-skill/references/report.md +27 -62
- package/src/skf-create-stack-skill/references/validate.md +35 -31
- package/src/skf-drop-skill/SKILL.md +20 -23
- package/src/skf-drop-skill/customize.toml +10 -0
- package/src/skf-drop-skill/references/execute.md +67 -36
- package/src/skf-drop-skill/references/headless-contract.md +18 -0
- package/src/skf-drop-skill/references/health-check.md +1 -13
- package/src/skf-drop-skill/references/report.md +44 -10
- package/src/skf-drop-skill/references/select.md +93 -48
- package/src/skf-drop-skill/scripts/dir-sizes.py +116 -0
- package/src/skf-export-skill/SKILL.md +17 -14
- package/src/skf-export-skill/assets/managed-section-format.md +2 -5
- package/src/skf-export-skill/customize.toml +10 -6
- package/src/skf-export-skill/references/generate-snippet.md +21 -35
- package/src/skf-export-skill/references/load-skill.md +44 -42
- package/src/skf-export-skill/references/multi-skill-mode.md +1 -1
- package/src/skf-export-skill/references/orphan-context-detection.md +11 -3
- package/src/skf-export-skill/references/package.md +27 -33
- package/src/skf-export-skill/references/preflight-snippet-root-probe.md +24 -5
- package/src/skf-export-skill/references/result-envelope.md +28 -0
- package/src/skf-export-skill/references/summary.md +11 -5
- package/src/skf-export-skill/references/token-report.md +42 -24
- package/src/skf-export-skill/references/update-context.md +32 -33
- package/src/skf-forger/SKILL.md +32 -39
- package/src/skf-forger/references/pipeline-mode.md +34 -0
- package/src/skf-forger/scripts/parse-pipeline.py +270 -0
- package/src/skf-quick-skill/SKILL.md +10 -60
- package/src/skf-quick-skill/customize.toml +9 -0
- package/src/skf-quick-skill/references/batch-mode.md +6 -4
- package/src/skf-quick-skill/references/compile.md +15 -52
- package/src/skf-quick-skill/references/ecosystem-check.md +5 -20
- package/src/skf-quick-skill/references/finalize.md +12 -6
- package/src/skf-quick-skill/references/halt-contract.md +54 -0
- package/src/skf-quick-skill/references/health-check.md +3 -4
- package/src/skf-quick-skill/references/quick-extract.md +7 -18
- package/src/skf-quick-skill/references/registry-resolution.md +1 -23
- package/src/skf-quick-skill/references/resolve-target.md +27 -34
- package/src/skf-quick-skill/references/write-and-validate.md +10 -25
- package/src/skf-refine-architecture/SKILL.md +16 -8
- package/src/skf-refine-architecture/customize.toml +9 -0
- package/src/skf-refine-architecture/references/compile.md +10 -8
- package/src/skf-refine-architecture/references/gap-analysis.md +21 -50
- package/src/skf-refine-architecture/references/health-check.md +1 -1
- package/src/skf-refine-architecture/references/improvements.md +9 -25
- package/src/skf-refine-architecture/references/init.md +9 -16
- package/src/skf-refine-architecture/references/issue-detection.md +10 -25
- package/src/skf-refine-architecture/references/refinement-rules.md +4 -16
- package/src/skf-refine-architecture/references/report.md +14 -11
- package/src/skf-rename-skill/SKILL.md +11 -21
- package/src/skf-rename-skill/customize.toml +10 -0
- package/src/skf-rename-skill/references/execute.md +112 -82
- package/src/skf-rename-skill/references/exit-codes.md +12 -0
- package/src/skf-rename-skill/references/report.md +16 -8
- package/src/skf-rename-skill/references/select.md +69 -42
- package/src/skf-rename-skill/scripts/skf-validate-rename-name.py +161 -0
- package/src/skf-setup/SKILL.md +21 -13
- package/src/skf-setup/customize.toml +10 -0
- package/src/skf-setup/references/auto-index.md +11 -10
- package/src/skf-setup/references/ccc-index.md +14 -15
- package/src/skf-setup/references/detect-and-tier.md +10 -8
- package/src/skf-setup/references/report.md +26 -32
- package/src/skf-setup/references/tier-rules.md +2 -32
- package/src/skf-setup/references/write-config.md +9 -10
- package/src/skf-test-skill/SKILL.md +10 -8
- package/src/skf-test-skill/customize.toml +2 -0
- package/src/skf-test-skill/references/coherence-check.md +19 -31
- package/src/skf-test-skill/references/coverage-check.md +111 -67
- package/src/skf-test-skill/references/detect-mode.md +10 -41
- package/src/skf-test-skill/references/external-validators.md +11 -19
- package/src/skf-test-skill/references/init.md +39 -21
- package/src/skf-test-skill/references/migration-section-rules.md +4 -4
- package/src/skf-test-skill/references/report.md +60 -40
- package/src/skf-test-skill/references/score.md +32 -64
- package/src/skf-test-skill/references/scoring-rules.md +6 -62
- package/src/skf-test-skill/references/source-access-protocol.md +15 -5
- package/src/skf-test-skill/references/step-hard-gate.md +1 -3
- package/src/skf-test-skill/scripts/aggregate-coherence.py +276 -0
- package/src/skf-test-skill/scripts/check-metadata-coherence.py +359 -0
- package/src/skf-test-skill/scripts/combine-external-scores.py +190 -0
- package/src/skf-test-skill/scripts/compute-score.py +135 -4
- package/src/skf-test-skill/scripts/reconcile-coverage.py +327 -0
- package/src/skf-test-skill/scripts/validate-inventory.py +251 -0
- package/src/skf-test-skill/scripts/verify-declared-numerator.py +192 -0
- package/src/skf-update-skill/SKILL.md +17 -5
- package/src/skf-update-skill/customize.toml +11 -6
- package/src/skf-update-skill/references/detect-changes.md +48 -36
- package/src/skf-update-skill/references/health-check.md +5 -11
- package/src/skf-update-skill/references/init.md +40 -32
- package/src/skf-update-skill/references/manual-section-rules.md +1 -2
- package/src/skf-update-skill/references/merge-conflict-rules.md +1 -52
- package/src/skf-update-skill/references/merge.md +13 -57
- package/src/skf-update-skill/references/re-extract.md +27 -25
- package/src/skf-update-skill/references/report.md +14 -7
- package/src/skf-update-skill/references/validate.md +32 -30
- package/src/skf-update-skill/references/write.md +86 -51
- package/src/skf-update-skill/scripts/skf-new-file-diff.py +167 -0
- package/src/skf-verify-stack/SKILL.md +11 -21
- package/src/skf-verify-stack/customize.toml +12 -3
- package/src/skf-verify-stack/references/coverage-patterns.md +1 -29
- package/src/skf-verify-stack/references/coverage.md +21 -10
- package/src/skf-verify-stack/references/exit-codes.md +14 -0
- package/src/skf-verify-stack/references/health-check.md +1 -1
- package/src/skf-verify-stack/references/init.md +20 -25
- package/src/skf-verify-stack/references/integration-verification-rules.md +10 -19
- package/src/skf-verify-stack/references/integrations.md +44 -49
- package/src/skf-verify-stack/references/report.md +28 -34
- package/src/skf-verify-stack/references/requirements.md +3 -3
- package/src/skf-verify-stack/references/synthesize.md +36 -39
- package/src/skf-verify-stack/scripts/skf-coverage-tally.py +196 -0
- package/src/skf-verify-stack/scripts/skf-report-delta.py +256 -0
- package/src/skf-verify-stack/scripts/skf-verdict-rollup.py +258 -0
- package/tools/cli/lib/ui.js +3 -2
- package/docs/deepwiki.md +0 -89
- package/src/skf-rename-skill/references/rebuild-context.md +0 -110
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
---
|
|
2
|
+
nextStepFile: 'step-02-strategy.md'
|
|
3
|
+
stateSchemaFile: 'assets/campaign-state-schema.json'
|
|
4
|
+
stateFile: '{campaignWorkspacePath}/_campaign-state.yaml'
|
|
5
|
+
briefFile: '{campaignWorkspacePath}/campaign-brief.yaml'
|
|
6
|
+
templateFile: '{briefTemplatePath}'
|
|
7
|
+
validateScript: 'scripts/campaign-validate-state.py'
|
|
8
|
+
manifestScript: 'scripts/campaign-parse-manifest.py'
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
<!-- Config: communicate in {communication_language}. -->
|
|
12
|
+
|
|
13
|
+
# Setup
|
|
14
|
+
|
|
15
|
+
## STEP GOAL:
|
|
16
|
+
|
|
17
|
+
Collect campaign inputs from the operator, create the initial `_campaign-state.yaml`, and generate `campaign-brief.yaml` so the campaign has a persistent starting point that survives context death.
|
|
18
|
+
|
|
19
|
+
This is the only step that creates the state file (it does not yet exist). All subsequent steps use **read-backup-modify-write** per the State Contract in `references/campaign-contracts.md`.
|
|
20
|
+
|
|
21
|
+
## RULES
|
|
22
|
+
|
|
23
|
+
- This step creates the state file — there is no existing state to read or back up.
|
|
24
|
+
- Validate the written state with `uv run {validateScript} --state-file {stateFile}` before generating the brief. HALT (exit code 3, `invalid-state`) on non-zero, surfacing the script's `errors[]`.
|
|
25
|
+
- If `{headless_mode}` is true, draw inputs from `--brief`/`--manifest` (On Activation step 4) and auto-proceed through confirmation gates with the default action, logging each auto-decision to the decision log.
|
|
26
|
+
|
|
27
|
+
## TASKS
|
|
28
|
+
|
|
29
|
+
### §1 — Collect Inputs
|
|
30
|
+
|
|
31
|
+
Accept from the operator (or, in headless mode, from the `--brief`/`--manifest` source parsed in On Activation):
|
|
32
|
+
|
|
33
|
+
- `campaign_name` — string identifier for this campaign run
|
|
34
|
+
- Target libraries — each entry requires:
|
|
35
|
+
- `name` — skill name
|
|
36
|
+
- `repo_url` — source repository URL
|
|
37
|
+
- `tier` — `"A"` (full pipeline) or `"B"` (batch)
|
|
38
|
+
- `pin` — version pin (string) or `null` for latest
|
|
39
|
+
- `depends_on` — array of skill names this target depends on (may be empty)
|
|
40
|
+
- `directive_path` (optional) — path to a `_campaign-directive.md` file with operator directives (contract: `references/campaign-directive-spec.md`)
|
|
41
|
+
- `architecture_doc_path` (optional) — path to the architecture document the verify (Stage 7) and refine (Stage 8) stages consume. If omitted here, those stages discover it at runtime (`docs/architecture.md`, then `_bmad-output/planning-artifacts/architecture.md`). Capturing it now persists the choice across resume and avoids re-prompting.
|
|
42
|
+
|
|
43
|
+
When seeding from `--manifest`, parse it deterministically: `uv run {manifestScript} <manifest-file>`. If the result's `errors[]` is non-empty (script exit 1), HALT (exit code 2, `invalid-input`) listing the offending line numbers — never run a partial target set. When seeding from `--brief`, read the existing `campaign-brief.yaml` directly.
|
|
44
|
+
|
|
45
|
+
If no targets can be collected (empty interactive input or empty `--brief`/`--manifest`), HALT (exit code 2, `invalid-input`) with guidance — a campaign needs at least one target.
|
|
46
|
+
|
|
47
|
+
### §2 — Health Queue Preference
|
|
48
|
+
|
|
49
|
+
Default to `"local"` (project-local findings queue). Present the opt-in prompt:
|
|
50
|
+
|
|
51
|
+
> Send anonymized quality findings to the shared improvement queue? [y/N]
|
|
52
|
+
|
|
53
|
+
- **y** — set `health_findings_queue` to `"improvement"`
|
|
54
|
+
- **N** (default) — keep `health_findings_queue` as `"local"`
|
|
55
|
+
|
|
56
|
+
In headless mode: auto-select `"local"` (N) and log the auto-decision.
|
|
57
|
+
|
|
58
|
+
### §3 — Build State Object
|
|
59
|
+
|
|
60
|
+
Construct `_campaign-state.yaml` in memory from collected inputs. Use the campaign-wide quality gate resolved in On Activation: `{qualityGateHard}` / `{qualityGateSoftTarget}` / `{qualityGateSoftFallback}`. Note: `repo_url` (collected in §1) is NOT part of the state schema — it belongs in the brief only (§5). The state schema enforces `additionalProperties: false`, so including it would fail validation.
|
|
61
|
+
|
|
62
|
+
```yaml
|
|
63
|
+
campaign:
|
|
64
|
+
name: "{campaign_name}"
|
|
65
|
+
started_at: "{current_iso8601_with_tz}"
|
|
66
|
+
last_updated: "{current_iso8601_with_tz}"
|
|
67
|
+
current_stage: 0
|
|
68
|
+
directive_path: "{directive_path or omit if not provided}"
|
|
69
|
+
architecture_doc_path: "{architecture_doc_path or omit if not provided}"
|
|
70
|
+
quality_gate:
|
|
71
|
+
hard: "{qualityGateHard}"
|
|
72
|
+
soft_target: {qualityGateSoftTarget}
|
|
73
|
+
soft_fallback: {qualityGateSoftFallback}
|
|
74
|
+
health_findings_queue: "{local or improvement}"
|
|
75
|
+
skills:
|
|
76
|
+
# One entry per target:
|
|
77
|
+
- name: "{target.name}"
|
|
78
|
+
status: "pending"
|
|
79
|
+
depends_on: [] # from target.depends_on
|
|
80
|
+
tier: "{target.tier}"
|
|
81
|
+
pin: null # from target.pin
|
|
82
|
+
brief_path: null # populated in step-05 once BS produces the skill's brief
|
|
83
|
+
skill_path: null
|
|
84
|
+
quality_score: null
|
|
85
|
+
workarounds_applied: []
|
|
86
|
+
started_at: null
|
|
87
|
+
completed_at: null
|
|
88
|
+
dependency_graph:
|
|
89
|
+
execution_order: [] # populated by step-02-strategy
|
|
90
|
+
circular_deps_detected: false
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### §4 — Write + Validate State
|
|
94
|
+
|
|
95
|
+
1. Ensure the directory `{campaignWorkspacePath}/` exists (create if missing).
|
|
96
|
+
2. Write the constructed state to `{stateFile}`. This is the initial creation — no `.bak` is needed for the first write; all subsequent steps use read-backup-modify-write.
|
|
97
|
+
3. Run `uv run {validateScript} --state-file {stateFile}`. On non-zero (invalid), **HALT** (exit 3) with the script's `errors[]` — do not proceed to brief generation with an invalid state file.
|
|
98
|
+
|
|
99
|
+
### §5 — Generate Brief
|
|
100
|
+
|
|
101
|
+
Populate `{templateFile}` with collected inputs and write to `{briefFile}`. Fill in:
|
|
102
|
+
|
|
103
|
+
- `campaign_name` — from collected input
|
|
104
|
+
- `created_at` — current ISO-8601 timestamp with timezone
|
|
105
|
+
- `targets` — array of target entries with `name`, `repo_url`, `tier`, `pin`, `depends_on`
|
|
106
|
+
- `quality_gate` — `{qualityGateHard}` / `{qualityGateSoftTarget}` / `{qualityGateSoftFallback}`
|
|
107
|
+
- `health_findings_queue` — from the §2 preference decision
|
|
108
|
+
- `architecture_doc_path` — from collected input, or empty string if not provided
|
|
109
|
+
- `notes` — operator-provided context, or empty string
|
|
110
|
+
|
|
111
|
+
The brief is a machine-readable snapshot enabling fresh-context resume.
|
|
112
|
+
|
|
113
|
+
## OUTPUT
|
|
114
|
+
|
|
115
|
+
Confirm state file creation and brief generation. Display summary:
|
|
116
|
+
|
|
117
|
+
- Campaign name
|
|
118
|
+
- Number of targets
|
|
119
|
+
- Health queue setting
|
|
120
|
+
|
|
121
|
+
Chain to `{nextStepFile}`.
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
---
|
|
2
|
+
nextStepFile: 'step-03-pins.md'
|
|
3
|
+
stateSchemaFile: 'assets/campaign-state-schema.json'
|
|
4
|
+
stateFile: '{campaignWorkspacePath}/_campaign-state.yaml'
|
|
5
|
+
backupFile: '{campaignWorkspacePath}/_campaign-state.yaml.bak'
|
|
6
|
+
depsScript: 'scripts/campaign-deps.py'
|
|
7
|
+
validateScript: 'scripts/campaign-validate-state.py'
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
<!-- Config: communicate in {communication_language}. -->
|
|
11
|
+
|
|
12
|
+
# Strategy
|
|
13
|
+
|
|
14
|
+
## STEP GOAL:
|
|
15
|
+
|
|
16
|
+
Compute the execution order from dependency edges, detect circular dependencies, and present a human-readable strategy view to the operator so the campaign plan is visible before execution begins.
|
|
17
|
+
|
|
18
|
+
## RULES
|
|
19
|
+
|
|
20
|
+
- This step uses the **read-backup-modify-write** pattern (state file exists from step-01).
|
|
21
|
+
- Validate state on load via `uv run {validateScript} --state-file {stateFile}`; HALT (exit 3) on non-zero.
|
|
22
|
+
- Write `execution_order` and `circular_deps_detected` to `dependency_graph`.
|
|
23
|
+
- Update `campaign.current_stage` to `1`.
|
|
24
|
+
- Update `campaign.last_updated` to current ISO-8601 with timezone on every write.
|
|
25
|
+
- If `{headless_mode}` is true, auto-proceed through confirmation gates with the default action and log each auto-decision.
|
|
26
|
+
|
|
27
|
+
## TASKS
|
|
28
|
+
|
|
29
|
+
### §1 — Read + Validate State
|
|
30
|
+
|
|
31
|
+
Load `{stateFile}`. Run `uv run {validateScript} --state-file {stateFile}`; on non-zero, HALT (exit 3) with the script's `errors[]`.
|
|
32
|
+
|
|
33
|
+
### §2 — Backup State
|
|
34
|
+
|
|
35
|
+
Copy `{stateFile}` to `{backupFile}` before any modification.
|
|
36
|
+
|
|
37
|
+
### §3 — Read Directive
|
|
38
|
+
|
|
39
|
+
If `campaign.directive_path` is set in state, load the file at that path and apply its contents as campaign-wide context for this stage's processing, per the directive contract in `references/campaign-directive-spec.md`. If the file is not found, continue without error (directive is optional).
|
|
40
|
+
|
|
41
|
+
### §4 — Compute Execution Order
|
|
42
|
+
|
|
43
|
+
Run the deterministic topological sort — do not hand-compute it:
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
uv run {depsScript} --compute --state-file {stateFile}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Parse the JSON output: `execution_order` (the ordered skill names — Kahn's sort with Tier A placed before Tier B within a dependency level), `circular_deps_detected` (bool), `cycle_participants` (the unplaced skills when a cycle exists, else null), and `tier_counts` (`{"A": n, "B": m}`, for the §7 strategy view). Script exit 1 signals an unorderable graph — a cycle or a dangling `depends_on` reference — handled at §5. Script exit 2 signals the helper could not read/parse the state file; HALT (exit code 2, `invalid-input`) surfacing its error.
|
|
50
|
+
|
|
51
|
+
### §5 — Handle Unorderable Graph
|
|
52
|
+
|
|
53
|
+
If the graph cannot be ordered (script exit 1), HALT (exit code 4, `circular-deps`) — the execution order is impossible, so do not proceed. Two cases:
|
|
54
|
+
|
|
55
|
+
- **Cycle** (`circular_deps_detected: true`): list `cycle_participants` and their mutual `depends_on` edges.
|
|
56
|
+
- **Dangling reference** (a `DANGLING_DEPENDENCY` error with no `execution_order`): name the skill and the unknown dependency it references.
|
|
57
|
+
|
|
58
|
+
### §6 — Write State
|
|
59
|
+
|
|
60
|
+
Set `dependency_graph.execution_order` to the computed order. Set `dependency_graph.circular_deps_detected` to the detection result. Set `campaign.current_stage` to `1`. Set `campaign.last_updated` to current ISO-8601 with timezone. Write to `{stateFile}`.
|
|
61
|
+
|
|
62
|
+
### §7 — Present Strategy View
|
|
63
|
+
|
|
64
|
+
Display a human-readable strategy summary to the operator (not written to a file — display only):
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
CAMPAIGN STRATEGY: {campaign_name}
|
|
68
|
+
|
|
69
|
+
EXECUTION ORDER:
|
|
70
|
+
1. {skill_name} [Tier {tier}] {pin or "latest"}
|
|
71
|
+
2. {skill_name} [Tier {tier}] {pin or "latest"} ← depends on: {dep1, dep2}
|
|
72
|
+
...
|
|
73
|
+
|
|
74
|
+
DEPENDENCY MAP:
|
|
75
|
+
{skill_a} → {skill_b}, {skill_c}
|
|
76
|
+
{skill_d} → (no dependencies)
|
|
77
|
+
...
|
|
78
|
+
|
|
79
|
+
QUALITY GATE:
|
|
80
|
+
Hard gate: {quality_gate.hard}
|
|
81
|
+
Soft target: {quality_gate.soft_target}%
|
|
82
|
+
Soft fallback: {quality_gate.soft_fallback}%
|
|
83
|
+
|
|
84
|
+
TIER DISTRIBUTION:
|
|
85
|
+
Tier A (full pipeline): {count}
|
|
86
|
+
Tier B (QS batch): {count}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Fill the TIER DISTRIBUTION counts from `tier_counts` in the §4 script output — do not re-tally `skills[]` by hand.
|
|
90
|
+
|
|
91
|
+
### §8 — Plan Confirmation Gate
|
|
92
|
+
|
|
93
|
+
The strategy view is the last review surface before a potentially long, mostly-unattended run begins. Present a confirmation gate:
|
|
94
|
+
|
|
95
|
+
- `[P]roceed` — begin execution (chain to `{nextStepFile}`).
|
|
96
|
+
- `[C]ancel` — stop now with exit code 12 (`user-cancelled`); state is intact and resumable. To change targets, edit the campaign brief (`{campaignWorkspacePath}/campaign-brief.yaml`) or re-run `campaign` (overwrite), then start again.
|
|
97
|
+
|
|
98
|
+
**HALT and wait for operator input.** In headless mode, auto-proceed with `[P]` and log "headless: auto-proceed past plan-confirmation gate" to the decision log.
|
|
99
|
+
|
|
100
|
+
## OUTPUT
|
|
101
|
+
|
|
102
|
+
Confirm strategy computed, display the strategy view, and resolve the §8 gate. Chain to `{nextStepFile}`.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
nextStepFile: 'step-04-provenance.md'
|
|
3
|
+
stateSchemaFile: 'assets/campaign-state-schema.json'
|
|
4
|
+
stateFile: '{campaignWorkspacePath}/_campaign-state.yaml'
|
|
5
|
+
backupFile: '{campaignWorkspacePath}/_campaign-state.yaml.bak'
|
|
6
|
+
briefFile: '{campaignWorkspacePath}/campaign-brief.yaml'
|
|
7
|
+
pinScript: 'scripts/campaign-validate-pins.py'
|
|
8
|
+
validateScript: 'scripts/campaign-validate-state.py'
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
<!-- Config: communicate in {communication_language}. -->
|
|
12
|
+
|
|
13
|
+
# Pins
|
|
14
|
+
|
|
15
|
+
## STEP GOAL:
|
|
16
|
+
|
|
17
|
+
Validate all version pins against real releases/branches before the campaign proceeds, catching invalid pins early with actionable suggestions.
|
|
18
|
+
|
|
19
|
+
## RULES
|
|
20
|
+
|
|
21
|
+
- This step uses the **read-backup-modify-write** pattern (state file exists from step-01).
|
|
22
|
+
- Validate state on load via `uv run {validateScript} --state-file {stateFile}`; HALT (exit 3) on non-zero.
|
|
23
|
+
- Update `campaign.current_stage` to `2`.
|
|
24
|
+
- Update `campaign.last_updated` to current ISO-8601 with timezone on every write.
|
|
25
|
+
- HALT (exit code 5, `invalid-pin`) on any invalid pin — invalid pins are errors, not gates.
|
|
26
|
+
- If `{headless_mode}` is true, auto-proceed through confirmation gates with the default action and log each auto-decision.
|
|
27
|
+
|
|
28
|
+
## TASKS
|
|
29
|
+
|
|
30
|
+
### §1 — Read + Validate State
|
|
31
|
+
|
|
32
|
+
Load `{stateFile}`. Run `uv run {validateScript} --state-file {stateFile}`; on non-zero, HALT (exit 3) with the script's `errors[]`.
|
|
33
|
+
|
|
34
|
+
### §2 — Read Brief
|
|
35
|
+
|
|
36
|
+
Load `{briefFile}`. Build a lookup map from `targets[].name` to `targets[].repo_url`. HALT (exit code 8, `missing-brief`) if the brief is missing or unreadable.
|
|
37
|
+
|
|
38
|
+
### §3 — Backup State
|
|
39
|
+
|
|
40
|
+
Copy `{stateFile}` to `{backupFile}` before any modification.
|
|
41
|
+
|
|
42
|
+
### §4 — Validate Pins
|
|
43
|
+
|
|
44
|
+
Run `uv run {pinScript} --state-file {stateFile} --brief-file {briefFile}`. If the script exits 2 (a required tool such as `gh` is unavailable, or a file is unreadable), HALT (exit code 2, `invalid-input`) surfacing its error — pins cannot be validated without `gh`. Otherwise parse the JSON output. For each result: if `status` is `"valid"` or `"resolved"`, the pin is good; if `"invalid"`, collect the failure with suggestions.
|
|
45
|
+
|
|
46
|
+
### §5 — Handle Invalid Pins
|
|
47
|
+
|
|
48
|
+
If ANY pins are invalid, collect ALL failures first (all-or-nothing pattern), then HALT (exit code 5, `invalid-pin`) with a clear error listing each invalid pin, the skill name, the attempted pin value, and suggested corrections. Do NOT partially proceed.
|
|
49
|
+
|
|
50
|
+
### §6 — Update State
|
|
51
|
+
|
|
52
|
+
For each skill where validation returned `status: "resolved"` (pin was null, latest release found), update `skill.pin` to the `resolved_ref` value. For `status: "valid"` where the input pin differs from `resolved_ref` (e.g., user said `2.0.0` but the actual tag is `v2.0.0`), update `skill.pin` to the `resolved_ref` so downstream steps use the exact ref name. Set `campaign.current_stage` to `2`. Set `campaign.last_updated`. Write to `{stateFile}`.
|
|
53
|
+
|
|
54
|
+
## OUTPUT
|
|
55
|
+
|
|
56
|
+
Display pin validation summary — for each skill: name, pin, resolved ref, ref type. Chain to `{nextStepFile}`.
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
nextStepFile: 'step-05-skill-loop.md'
|
|
3
|
+
stateSchemaFile: 'assets/campaign-state-schema.json'
|
|
4
|
+
stateFile: '{campaignWorkspacePath}/_campaign-state.yaml'
|
|
5
|
+
backupFile: '{campaignWorkspacePath}/_campaign-state.yaml.bak'
|
|
6
|
+
briefFile: '{campaignWorkspacePath}/campaign-brief.yaml'
|
|
7
|
+
provenanceScript: 'scripts/campaign-provenance.py'
|
|
8
|
+
validateScript: 'scripts/campaign-validate-state.py'
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
<!-- Config: communicate in {communication_language}. -->
|
|
12
|
+
|
|
13
|
+
# Provenance
|
|
14
|
+
|
|
15
|
+
## STEP GOAL:
|
|
16
|
+
|
|
17
|
+
Verify that all target repositories are accessible and record the exact commit SHA for each target, establishing the provenance baseline for the campaign.
|
|
18
|
+
|
|
19
|
+
## RULES
|
|
20
|
+
|
|
21
|
+
- This step uses the **read-backup-modify-write** pattern.
|
|
22
|
+
- Reads the brief for `repo_url` (not in state — `repo_url` is NOT part of the state schema).
|
|
23
|
+
- Any inaccessible repo halts the campaign — all targets must be reachable before skill processing begins.
|
|
24
|
+
- Validate state on load via `uv run {validateScript} --state-file {stateFile}`; HALT (exit 3) on non-zero.
|
|
25
|
+
- Update `campaign.current_stage` to `3`.
|
|
26
|
+
- Update `campaign.last_updated` to current ISO-8601 with timezone on every write.
|
|
27
|
+
- If `{headless_mode}` is true, auto-proceed through confirmation gates with the default action and log each auto-decision.
|
|
28
|
+
|
|
29
|
+
## TASKS
|
|
30
|
+
|
|
31
|
+
### §1 — Read + Validate State
|
|
32
|
+
|
|
33
|
+
Load `{stateFile}`. Run `uv run {validateScript} --state-file {stateFile}`; on non-zero, HALT (exit 3) with the script's `errors[]`.
|
|
34
|
+
|
|
35
|
+
### §2 — Read Brief
|
|
36
|
+
|
|
37
|
+
Load `{briefFile}` only to confirm it parses (the provenance script reads it directly). HALT (exit code 8, `missing-brief`) if the brief is missing or unreadable.
|
|
38
|
+
|
|
39
|
+
### §3 — Backup State
|
|
40
|
+
|
|
41
|
+
Copy `{stateFile}` to `{backupFile}` before any modification.
|
|
42
|
+
|
|
43
|
+
### §4 — Verify Repo Access + Record Commit SHAs
|
|
44
|
+
|
|
45
|
+
Run the deterministic provenance check — do not parse repo URLs or shell out to `gh` by hand:
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
uv run {provenanceScript} --state-file {stateFile} --brief-file {briefFile}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
The script resolves `{owner}/{repo}` from each `repo_url` (tolerating `.git`/trailing slashes/SSH form), picks the ref (the skill's `pin`, else the repo default branch), runs `gh repo view` + `gh api commits`, and emits `results[]` with `commit_sha` and `status` per skill, plus `all_accessible`, `inaccessible_count`, and `systemic_hint`. Exit 0 = all accessible, 1 = one or more inaccessible, 2 = error (missing files, bad YAML, `gh` not installed). On script exit 2, HALT (exit code 2, `invalid-input`) surfacing the error — repo access cannot be verified without `gh`.
|
|
52
|
+
|
|
53
|
+
### §5 — Handle Inaccessible Repos
|
|
54
|
+
|
|
55
|
+
If `all_accessible` is `false` (script exit 1), HALT (exit code 6, `inaccessible-repo`). When the script returns a non-null `systemic_hint` (every target failed the same way — e.g. unauthenticated `gh`, no network, rate limit), present that single root-cause line instead of a wall of near-identical per-repo errors. Otherwise list each inaccessible repo, its URL, and its error. Do NOT partially proceed — all repos must be verified before writing state.
|
|
56
|
+
|
|
57
|
+
### §6 — Write State
|
|
58
|
+
|
|
59
|
+
Set each skill's `commit_sha` from the script's `results[]`. Set `campaign.current_stage` to `3`. Set `campaign.last_updated` to current ISO-8601 with timezone. Write to `{stateFile}`.
|
|
60
|
+
|
|
61
|
+
## OUTPUT
|
|
62
|
+
|
|
63
|
+
Display provenance summary — for each target, show name, repo URL, and recorded commit SHA. Chain to `{nextStepFile}`.
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
---
|
|
2
|
+
nextStepFile: 'step-06-batch.md'
|
|
3
|
+
stateSchemaFile: 'assets/campaign-state-schema.json'
|
|
4
|
+
stateFile: '{campaignWorkspacePath}/_campaign-state.yaml'
|
|
5
|
+
backupFile: '{campaignWorkspacePath}/_campaign-state.yaml.bak'
|
|
6
|
+
briefFile: '{campaignWorkspacePath}/campaign-brief.yaml'
|
|
7
|
+
depsScript: 'scripts/campaign-deps.py'
|
|
8
|
+
kickoffTemplate: '{kickoffTemplatePath}'
|
|
9
|
+
kickoffScript: 'scripts/campaign-render-kickoff.py'
|
|
10
|
+
validateScript: 'scripts/campaign-validate-state.py'
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
<!-- Config: communicate in {communication_language}. -->
|
|
14
|
+
|
|
15
|
+
# Skill Loop
|
|
16
|
+
|
|
17
|
+
## STEP GOAL:
|
|
18
|
+
|
|
19
|
+
Iterate skills in `dependency_graph.execution_order`, processing each Tier A skill through the full pipeline while enforcing dependency gates. Write state after each skill completes to survive context death between skills.
|
|
20
|
+
|
|
21
|
+
## RULES
|
|
22
|
+
|
|
23
|
+
- This step uses the **read-backup-modify-write** pattern.
|
|
24
|
+
- Validate state on load via `uv run {validateScript} --state-file {stateFile}`; HALT (exit 3) on non-zero.
|
|
25
|
+
- Update `campaign.current_stage` to `4`.
|
|
26
|
+
- Update `campaign.last_updated` to current ISO-8601 with timezone on every write.
|
|
27
|
+
- Write state after EACH skill completes (not just at end) — context death between skills must be survivable.
|
|
28
|
+
- The per-skill pipeline body (§5.2) runs inline, not in a delegated subagent: AN→BS→CS→TS are nested skill activations, and a subagent cannot spawn further subagents — running inline keeps the full pipeline reachable and writes each skill's state before the next begins.
|
|
29
|
+
- If `{headless_mode}` is true, auto-proceed through confirmation gates. Dependency gate blocks default to HALT (safest — never silently skip dependencies).
|
|
30
|
+
|
|
31
|
+
## TASKS
|
|
32
|
+
|
|
33
|
+
### §1 — Read + Validate State
|
|
34
|
+
|
|
35
|
+
Load `{stateFile}`. Run `uv run {validateScript} --state-file {stateFile}`; on non-zero, HALT (exit 3) with the script's `errors[]`.
|
|
36
|
+
|
|
37
|
+
### §2 — Read Brief
|
|
38
|
+
|
|
39
|
+
Load `{briefFile}`. Build a lookup map from `targets[].name` to `targets[].repo_url`. HALT (exit code 8, `missing-brief`) if the brief is missing or unreadable.
|
|
40
|
+
|
|
41
|
+
### §3 — Read Directive
|
|
42
|
+
|
|
43
|
+
If `campaign.directive_path` is set in state, load the file at that path and apply its contents as campaign-wide context for all skill processing, per the directive contract in `references/campaign-directive-spec.md`. If the file is not found, continue without error (directive is optional).
|
|
44
|
+
|
|
45
|
+
### §4 — Dependency Gate Check
|
|
46
|
+
|
|
47
|
+
For each skill in `dependency_graph.execution_order`, before processing:
|
|
48
|
+
|
|
49
|
+
1. Skip Tier B skills — they are processed in step-06 via batch mode.
|
|
50
|
+
2. Skip skills whose status is already `"completed"`, `"failed"`, or `"skipped"` (resume support).
|
|
51
|
+
3. Run `uv run {depsScript} --check --state-file {stateFile} --skill {skill_name}`.
|
|
52
|
+
4. If `ready: true` — proceed to §5 for this skill.
|
|
53
|
+
5. If `ready: false` — present the blocked skill and its unmet dependencies:
|
|
54
|
+
- `[S]kip` — mark skill as `"skipped"`, backup and write state, continue to next skill.
|
|
55
|
+
- `[F]orce` — re-run with `--force`, proceed to §5 despite unmet deps.
|
|
56
|
+
- `[H]alt` — stop the campaign loop. (Default in headless mode.)
|
|
57
|
+
6. **Deadlock detection:** after iterating through all remaining skills and finding none ready, present the same recovery menu as §4.5, scoped to the mutually-blocked set (this is the strictly harder situation, so it must not get worse UX than a single blocked skill):
|
|
58
|
+
- List the blocked skills and their unmet dependencies.
|
|
59
|
+
- `[F]orce one` — choose a skill to re-run with `--force` and resume the loop from it.
|
|
60
|
+
- `[S]kip one` — choose a skill to mark `"skipped"`, backup and write state, then re-evaluate readiness.
|
|
61
|
+
- `[H]alt` — stop the campaign loop with exit code 7 (`dependency-deadlock`). **Default in headless mode** (never silently force or skip a dependency). Log the chosen action to the decision log.
|
|
62
|
+
|
|
63
|
+
### §5 — Per-Skill Processing
|
|
64
|
+
|
|
65
|
+
For each ready Tier A skill:
|
|
66
|
+
|
|
67
|
+
1. **Activate** — set `status` to `"active"`, set `started_at` to current ISO-8601 with timezone. Backup and write state.
|
|
68
|
+
2. **Execute pipeline:**
|
|
69
|
+
- **Pre-apply** — apply known workarounds before generation by running the shared pre-apply helper against the skill's working directory:
|
|
70
|
+
```
|
|
71
|
+
uv run {project-root}/_bmad/skf/shared/scripts/skf-preapply.py --target-dir <skill-working-dir> --log-dir {campaignWorkspacePath}
|
|
72
|
+
```
|
|
73
|
+
(During development the helper lives at `src/shared/scripts/skf-preapply.py`.) Parse `applied[]` from the JSON output and capture the list of applied workarounds. Pre-apply is best-effort: if the helper is missing or exits non-zero, log a warning and proceed — it is not a gate.
|
|
74
|
+
- **Kickoff emit** — render the mechanical placeholders deterministically, then fill the three judgment slots. Run:
|
|
75
|
+
```
|
|
76
|
+
uv run {kickoffScript} --state-file {stateFile} --brief-file {briefFile} --skill {skill_name} --template {kickoffTemplate} --workarounds '<JSON list of applied workarounds from pre-apply>'
|
|
77
|
+
```
|
|
78
|
+
The script fills `{{campaign_name}}`, `{{current_stage}}`, `{{quality_gate_summary}}`, `{{skill_name}}`, `{{skill_tier}}`, `{{pin}}`, `{{commit_sha}}`, `{{repo_url}}`, `{{workarounds_list}}`, and `{{dependency_status_table}}` from state + brief. Then fill the three judgment slots that remain in the rendered output:
|
|
79
|
+
- `{{brief_summary}}` — a concise summary of this target's brief entry (name, repo_url, tier, pin, depends_on). The per-skill brief does NOT exist yet at kickoff — BS produces it during this pipeline run (see below), so do not read `brief_path`; summarize the campaign brief's target entry instead.
|
|
80
|
+
- `{{persistent_facts}}` — the campaign-wide persistent facts resolved in On Activation (literal sentences and loaded `file:` contents), as a bullet list, or "None" if empty. This is how house style/guardrails reach every skill's pipeline.
|
|
81
|
+
- `{{directive_content}}` — raw content of the file at `campaign.directive_path`, or "No directive configured" if unset/missing.
|
|
82
|
+
Present the completed kickoff message as the context for the skill's pipeline run.
|
|
83
|
+
- **AN → BS → CS → TS** — standard forge pipeline for this skill. When BS (Brief Synthesis) produces the skill's brief, set `skills[current].brief_path` to the brief path from the BS result envelope so the field the schema declares is populated and available for resume and reporting.
|
|
84
|
+
- **Doc-rot check** — grep feeder artifacts for corrections emitted during the pipeline run. Append any doc-rot findings to the skill's `workarounds_applied` array (prefixed with `[doc-rot]`) so they survive state write and are available for §6 propagation.
|
|
85
|
+
3. **Record results:**
|
|
86
|
+
- On success: set `status` to `"completed"`, set `completed_at` to current ISO-8601 with timezone, record `quality_score`. Backup and write state.
|
|
87
|
+
- On failure: set `status` to `"failed"`. Log the failure reason (the sub-skill's `halt_reason`/exit code, or "unparseable result envelope") to the decision log so `campaign status` and the report surface *why* a skill failed without the operator opening sub-skill logs. Backup and write state. Downstream skills whose `depends_on` does NOT include the failed skill continue processing normally; those that DO depend on it are blocked at §4's dependency gate.
|
|
88
|
+
|
|
89
|
+
### §6 — Propagate Findings
|
|
90
|
+
|
|
91
|
+
After each completed skill, propagate quality findings and doc-rot corrections to campaign-level tracking (`workarounds_applied`, `quality_score`).
|
|
92
|
+
|
|
93
|
+
### §7 — Loop Completion
|
|
94
|
+
|
|
95
|
+
When all Tier A skills in `execution_order` are processed (completed, failed, or skipped):
|
|
96
|
+
|
|
97
|
+
1. Set `campaign.current_stage` to `4`.
|
|
98
|
+
2. Set `campaign.last_updated` to current ISO-8601 with timezone.
|
|
99
|
+
3. Backup and write state.
|
|
100
|
+
|
|
101
|
+
## OUTPUT
|
|
102
|
+
|
|
103
|
+
Display per-skill summary: name, status, quality_score (if completed). Chain to `{nextStepFile}`.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
---
|
|
2
|
+
nextStepFile: 'step-07-capstone.md'
|
|
3
|
+
stateSchemaFile: 'assets/campaign-state-schema.json'
|
|
4
|
+
stateFile: '{campaignWorkspacePath}/_campaign-state.yaml'
|
|
5
|
+
backupFile: '{campaignWorkspacePath}/_campaign-state.yaml.bak'
|
|
6
|
+
briefFile: '{campaignWorkspacePath}/campaign-brief.yaml'
|
|
7
|
+
batchFile: '{campaignWorkspacePath}/_batch-input.txt'
|
|
8
|
+
batchScript: 'scripts/campaign-render-batch.py'
|
|
9
|
+
validateScript: 'scripts/campaign-validate-state.py'
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
<!-- Config: communicate in {communication_language}. -->
|
|
13
|
+
|
|
14
|
+
# Tier B Batch
|
|
15
|
+
|
|
16
|
+
## STEP GOAL:
|
|
17
|
+
|
|
18
|
+
Batch all Tier B skills through QS `--batch` mode, recording per-skill results in campaign state. Tier B skills use a faster, simpler path than the full Tier A pipeline — QS handles each target end-to-end in a single invocation.
|
|
19
|
+
|
|
20
|
+
## RULES
|
|
21
|
+
|
|
22
|
+
- This step uses the **read-backup-modify-write** pattern.
|
|
23
|
+
- Validate state on load via `uv run {validateScript} --state-file {stateFile}`; HALT (exit 3) on non-zero.
|
|
24
|
+
- Update `campaign.last_updated` to current ISO-8601 with timezone on every write.
|
|
25
|
+
- Update `campaign.current_stage` to `5`.
|
|
26
|
+
- If `{headless_mode}` is true, auto-proceed through confirmation gates. QS `--batch` implies headless.
|
|
27
|
+
|
|
28
|
+
## TASKS
|
|
29
|
+
|
|
30
|
+
### §1 — Read + Validate State
|
|
31
|
+
|
|
32
|
+
Load `{stateFile}`. Run `uv run {validateScript} --state-file {stateFile}`; on non-zero, HALT (exit 3) with the script's `errors[]`.
|
|
33
|
+
|
|
34
|
+
### §2 — Read Directive
|
|
35
|
+
|
|
36
|
+
If `campaign.directive_path` is set in state, load the file at that path and apply its contents as campaign-wide context for this stage's processing, per the directive contract in `references/campaign-directive-spec.md`. If the file is not found, continue without error (directive is optional).
|
|
37
|
+
|
|
38
|
+
### §3 — Identify Tier B Skills
|
|
39
|
+
|
|
40
|
+
Filter `skills[]` for entries where `tier == "B"` and `status == "pending"`. Skip skills with status `"completed"`, `"failed"`, or `"skipped"` (resume support — a previous run may have partially completed the batch).
|
|
41
|
+
|
|
42
|
+
If no Tier B skills need processing, skip to §7 (Stage Completion) — the batch stage completes immediately when all Tier B skills are already handled.
|
|
43
|
+
|
|
44
|
+
### §4 — Generate Batch File
|
|
45
|
+
|
|
46
|
+
Generate the QS `--batch` input file deterministically:
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
uv run {batchScript} --state-file {stateFile} --brief-file {briefFile} -o {batchFile}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The script filters `skills[]` for `tier == "B" && status == "pending"`, looks up each skill's `repo_url` from the brief's `targets[]` (repo URLs live in the brief, not the state schema), and writes one line per skill at `{batchFile}` in the exact single-target shape QS parses (see `src/skf-quick-skill/references/batch-mode.md`) — the line format is owned once by the script, not re-derived here. It emits a JSON summary (`written`, `count`, `skipped_non_tierB`, `skipped_non_pending`) on stderr.
|
|
53
|
+
|
|
54
|
+
HALT on non-zero exit: exit code 8 (`missing-brief`) when the brief is missing/unreadable **or** a pending Tier B skill has no matching brief target; exit code 2 (`invalid-input`) on a state file/parse error.
|
|
55
|
+
|
|
56
|
+
### §5 — Execute QS Batch
|
|
57
|
+
|
|
58
|
+
Set each pending Tier B skill to `status: "active"` and `started_at` to current ISO-8601 with timezone. Backup `{stateFile}` to `{backupFile}`, then write the updated state.
|
|
59
|
+
|
|
60
|
+
Invoke QS in `--batch` mode with the generated batch file:
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
skf-quick-skill --batch {batchFile}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
QS `--batch` implies `--headless`. Capture per-skill results from the QS batch output — each target reports success/failure, skill path, and quality score.
|
|
67
|
+
|
|
68
|
+
### §6 — Record Results
|
|
69
|
+
|
|
70
|
+
For each Tier B skill in the batch:
|
|
71
|
+
|
|
72
|
+
1. If QS reports success:
|
|
73
|
+
- Set `status` to `"completed"`
|
|
74
|
+
- Set `completed_at` to current ISO-8601 with timezone
|
|
75
|
+
- Record `quality_score` from QS output
|
|
76
|
+
- Record `skill_path` from QS output
|
|
77
|
+
2. If QS reports failure:
|
|
78
|
+
- Set `status` to `"failed"`
|
|
79
|
+
|
|
80
|
+
After all updates: backup `{stateFile}` to `{backupFile}`, then write the updated state.
|
|
81
|
+
|
|
82
|
+
### §7 — Stage Completion
|
|
83
|
+
|
|
84
|
+
Set `campaign.current_stage` to `5`. Update `campaign.last_updated` to current ISO-8601 with timezone. Backup `{stateFile}` to `{backupFile}`, then write the updated state.
|
|
85
|
+
|
|
86
|
+
## OUTPUT
|
|
87
|
+
|
|
88
|
+
Display per-skill batch summary: name, status, quality_score (if completed). Chain to `{nextStepFile}`.
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
nextStepFile: 'step-08-verify.md'
|
|
3
|
+
stateSchemaFile: 'assets/campaign-state-schema.json'
|
|
4
|
+
stateFile: '{campaignWorkspacePath}/_campaign-state.yaml'
|
|
5
|
+
backupFile: '{campaignWorkspacePath}/_campaign-state.yaml.bak'
|
|
6
|
+
validateScript: 'scripts/campaign-validate-state.py'
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
<!-- Config: communicate in {communication_language}. -->
|
|
10
|
+
|
|
11
|
+
# Capstone
|
|
12
|
+
|
|
13
|
+
## STEP GOAL:
|
|
14
|
+
|
|
15
|
+
Compose a capstone stack skill from all completed individual skills using SS compose-mode. The capstone represents the final integrated view of all campaign skills — a single stack skill that documents how the constituent libraries connect.
|
|
16
|
+
|
|
17
|
+
## RULES
|
|
18
|
+
|
|
19
|
+
- This step uses the **read-backup-modify-write** pattern.
|
|
20
|
+
- Validate state on load via `uv run {validateScript} --state-file {stateFile}`; HALT (exit 3) on non-zero.
|
|
21
|
+
- Update `campaign.last_updated` to current ISO-8601 with timezone on every write.
|
|
22
|
+
- Update `campaign.current_stage` to `6`.
|
|
23
|
+
- If `{headless_mode}` is true, auto-proceed through confirmation gates. SS compose-mode supports headless.
|
|
24
|
+
|
|
25
|
+
## TASKS
|
|
26
|
+
|
|
27
|
+
### §1 — Read + Validate State
|
|
28
|
+
|
|
29
|
+
Load `{stateFile}`. Run `uv run {validateScript} --state-file {stateFile}`; on non-zero, HALT (exit 3) with the script's `errors[]`.
|
|
30
|
+
|
|
31
|
+
### §2 — Collect Completed Skills
|
|
32
|
+
|
|
33
|
+
Gather all skills from `skills[]` with `status == "completed"` — this includes both Tier A skills (processed in step-05) and Tier B skills (processed in step-06). Extract their `skill_path` values.
|
|
34
|
+
|
|
35
|
+
If no completed skills exist, do NOT HALT — a campaign where everything failed is exactly when the operator most needs the downstream diagnostic report. Set `campaign.capstone` to `null`, warn ("No completed skills — skipping capstone composition; verification and the campaign report will still run so failures are explained"), log the skip to the decision log, and skip directly to §5 (Stage Completion) so the chain continues to verify → … → the report. step-10 (export) and step-11 (report) already handle the zero-completed case.
|
|
36
|
+
|
|
37
|
+
### §3 — Invoke SS Compose-Mode
|
|
38
|
+
|
|
39
|
+
Invoke `skf-create-stack-skill` in compose-mode with:
|
|
40
|
+
|
|
41
|
+
- The collected `skill_path` values as input skills
|
|
42
|
+
- `campaign.name` as the stack identifier
|
|
43
|
+
|
|
44
|
+
Capture the result: stack skill path and quality score from the SS result output (`SKF_STACK_RESULT_JSON`).
|
|
45
|
+
|
|
46
|
+
### §4 — Record Capstone Results
|
|
47
|
+
|
|
48
|
+
Persist the capstone outcome to `campaign.capstone` in the state (campaign-level summary; the composed skill itself lives at `skill_path`):
|
|
49
|
+
|
|
50
|
+
- `campaign.capstone.skill_path` — stack skill path (from SS result)
|
|
51
|
+
- `campaign.capstone.quality_score` — quality score (from SS result)
|
|
52
|
+
- `campaign.capstone.verified` — `null` for now; set by the verify stage (step-08) once the stack is checked
|
|
53
|
+
- `campaign.capstone.completed_at` — current ISO-8601 with timezone
|
|
54
|
+
|
|
55
|
+
The capstone is a derived artifact — it is **not** tracked as a skill entry in the `skills[]` array. Its campaign-level summary lives in `campaign.capstone`; the constituent skill list and any verbose detail are reported in the step output and are available to downstream steps (verify, refine).
|
|
56
|
+
|
|
57
|
+
### §5 — Stage Completion
|
|
58
|
+
|
|
59
|
+
Set `campaign.current_stage` to `6`. Update `campaign.last_updated` to current ISO-8601 with timezone. Backup `{stateFile}` to `{backupFile}`, then write the updated state (including `campaign.capstone` from §4).
|
|
60
|
+
|
|
61
|
+
## OUTPUT
|
|
62
|
+
|
|
63
|
+
Display capstone summary: stack skill name, path, quality score, and the list of constituent skills. Chain to `{nextStepFile}`.
|