bmad-module-skill-forge 2.0.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/docs/_data/pinned.yaml +1 -1
- package/package.json +2 -2
- package/src/knowledge/skill-lifecycle.md +1 -1
- package/src/module-help.csv +2 -2
- 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-detect-docs.py +232 -1
- package/src/shared/scripts/skf-detect-language.py +77 -0
- package/src/shared/scripts/skf-detect-tools.py +105 -2
- package/src/shared/scripts/skf-enumerate-stack-skills.py +111 -2
- 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-manifest-ops.py +67 -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-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 +39 -1
- 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 +1 -1
- package/src/shared/scripts/skf-verify-no-trace.py +214 -0
- package/src/shared/scripts/skf-verify-provenance-completeness.py +439 -0
- package/src/skf-analyze-source/SKILL.md +17 -32
- 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 +42 -180
- 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/customize.toml +14 -0
- package/src/skf-brief-skill/references/analyze-target.md +6 -14
- package/src/skf-brief-skill/references/confirm-brief.md +2 -14
- package/src/skf-brief-skill/references/draft-checkpoint.md +8 -8
- package/src/skf-brief-skill/references/gather-intent.md +19 -22
- 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 +4 -14
- package/src/skf-brief-skill/references/step-auto-brief.md +1 -5
- package/src/skf-brief-skill/references/step-auto-validate.md +1 -5
- package/src/skf-brief-skill/references/version-resolution.md +1 -1
- package/src/skf-brief-skill/references/write-brief.md +17 -10
- package/src/skf-campaign/SKILL.md +15 -84
- package/src/skf-campaign/customize.toml +2 -0
- package/src/skf-campaign/manifest.yaml +4 -0
- package/src/skf-campaign/references/campaign-contracts.md +67 -0
- package/src/skf-campaign/references/campaign-directive-spec.md +14 -103
- package/src/skf-campaign/references/step-01-setup.md +4 -5
- package/src/skf-campaign/references/step-02-strategy.md +8 -3
- package/src/skf-campaign/references/step-03-pins.md +1 -1
- package/src/skf-campaign/references/step-04-provenance.md +1 -1
- package/src/skf-campaign/references/step-05-skill-loop.md +1 -1
- package/src/skf-campaign/references/step-06-batch.md +7 -6
- package/src/skf-campaign/references/step-11-maintenance.md +2 -2
- package/src/skf-campaign/references/step-resume.md +9 -8
- package/src/skf-campaign/scripts/campaign-deps.py +10 -1
- package/src/skf-campaign/scripts/campaign-render-batch.py +199 -0
- package/src/skf-campaign/scripts/campaign-status.py +162 -0
- package/src/skf-campaign/templates/campaign-brief-template.yaml +1 -1
- package/src/skf-create-skill/SKILL.md +14 -3
- package/src/skf-create-skill/assets/compile-assembly-rules.md +17 -38
- 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 +34 -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 +14 -29
- package/src/skf-create-skill/references/extraction-patterns-tracing.md +1 -1
- package/src/skf-create-skill/references/extraction-patterns.md +7 -7
- package/src/skf-create-skill/references/generate-artifacts.md +9 -23
- package/src/skf-create-skill/references/health-check.md +1 -1
- package/src/skf-create-skill/references/load-brief.md +16 -18
- package/src/skf-create-skill/references/report.md +12 -15
- package/src/skf-create-skill/references/source-resolution-protocols.md +3 -3
- package/src/skf-create-skill/references/step-auto-shard.md +52 -25
- package/src/skf-create-skill/references/step-doc-rot.md +30 -12
- package/src/skf-create-skill/references/step-doc-sources.md +2 -2
- package/src/skf-create-skill/references/sub/ccc-discover.md +2 -13
- package/src/skf-create-skill/references/sub/fetch-docs.md +8 -50
- 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 +59 -28
- 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 +51 -31
- 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 +42 -10
- package/src/skf-drop-skill/references/select.md +88 -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 +27 -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 +14 -7
- package/src/skf-refine-architecture/customize.toml +9 -0
- package/src/skf-refine-architecture/references/compile.md +9 -7
- 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 +13 -10
- 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 +107 -78
- 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 +20 -12
- package/src/skf-setup/customize.toml +10 -0
- package/src/skf-setup/references/auto-index.md +9 -10
- package/src/skf-setup/references/ccc-index.md +14 -15
- package/src/skf-setup/references/detect-and-tier.md +6 -8
- package/src/skf-setup/references/report.md +22 -31
- 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 +109 -75
- 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 +38 -20
- 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 +6 -6
- 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 +131 -1
- 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 +14 -0
- package/src/skf-update-skill/references/detect-changes.md +19 -37
- package/src/skf-update-skill/references/health-check.md +3 -9
- package/src/skf-update-skill/references/init.md +39 -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 +12 -24
- 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/src/skf-rename-skill/references/rebuild-context.md +0 -110
|
@@ -2,25 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
## agentskills.io Compliant Format
|
|
4
4
|
|
|
5
|
-
### Frontmatter
|
|
5
|
+
### Frontmatter
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
---
|
|
9
|
-
name: {skill-name}
|
|
10
|
-
description: >
|
|
11
|
-
{Trigger-optimized description of what the skill does and when to use it.
|
|
12
|
-
Include specific keywords for agent discovery.
|
|
13
|
-
Mention what NOT to use it for if applicable.
|
|
14
|
-
1-1024 characters.}
|
|
15
|
-
---
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
**Frontmatter rules (agentskills.io specification):**
|
|
19
|
-
|
|
20
|
-
- `name`: 1-64 characters, lowercase alphanumeric + hyphens only, must match parent directory name. Prefer gerund form (`processing-pdfs`, `analyzing-spreadsheets`) for clarity; noun phrases and action-oriented forms are acceptable alternatives.
|
|
21
|
-
- `description`: 1-1024 characters, trigger-optimized for agent matching. MUST use third-person voice ("Processes..." not "I can..." or "You can...") AND include a trigger phrase ("Use when ...", "Triggers on ...", "Reach for this when ..."). When using "Use when ", follow with a gerund (`Use when building/processing/analyzing X…`) or noun-phrase clause — never a bare indicative verb, since `skill-check --fix` will prepend a literal "Use when " to descriptions missing the phrase. See `skf-brief-skill/assets/description-voice-examples.md`.
|
|
22
|
-
- Only 6 fields permitted: `name`, `description`, `license`, `compatibility`, `metadata`, `allowed-tools`
|
|
23
|
-
- `version` and `author` belong in metadata.json, NOT in frontmatter
|
|
7
|
+
The authoritative frontmatter contract — permitted fields, the `name`/`description` rules, the trigger-phrase/voice requirements, and the no-angle-brackets rule — is owned by `assets/compile-assembly-rules.md` (## Frontmatter). This catalog does not restate it (both files load together at compile.md §1).
|
|
24
8
|
|
|
25
9
|
### Two-Tier Section Structure
|
|
26
10
|
|
|
@@ -49,91 +33,16 @@ SKILL.md uses a two-tier structure to ensure actionable content survives `split-
|
|
|
49
33
|
| 10 | **Full Type Definitions** | All types, interfaces, enums with full field details |
|
|
50
34
|
| 11 | **Full Integration Patterns** | Co-import patterns, adapter details, pipeline internals (Forge/Deep only) |
|
|
51
35
|
|
|
52
|
-
####
|
|
36
|
+
#### Section Conditionality
|
|
53
37
|
|
|
54
|
-
- Tier 1 sections are assembled first — they form the standalone body
|
|
55
|
-
- Tier 2 sections are assembled after — they are progressive disclosure detail
|
|
56
|
-
- Tier 1 sections are kept short enough that `split-body` targets the larger Tier 2 sections (`## Full` headings) into `references/`
|
|
57
|
-
- After split-body, SKILL.md retains all Tier 1 content — actionable without loading references
|
|
58
|
-
- An agent loading only SKILL.md (no references) must get enough to act
|
|
59
38
|
- **Section 4b (Migration & Deprecation Warnings)** is conditional: only emitted for Deep tier when T2-future annotations exist. Quick/Forge/Forge+ tiers and Deep tiers without T2-future annotations omit it entirely (no empty section). Parsers and validators must treat this section as optional.
|
|
60
39
|
- **Section 7b (Scripts & Assets)** is conditional: only emitted when `scripts_inventory` or `assets_inventory` is non-empty. Omitted entirely when no scripts or assets are detected. Parsers and validators must treat this section as optional.
|
|
61
40
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
When `scope.type: "component-library"`, these section formats replace their standard counterparts. All other sections (Overview, Common Workflows, Architecture, CLI, Manual Sections, etc.) use the standard format.
|
|
65
|
-
|
|
66
|
-
#### Section 4 — Component Catalog (replaces Key API Summary)
|
|
67
|
-
|
|
68
|
-
```markdown
|
|
69
|
-
## Component Catalog
|
|
70
|
-
|
|
71
|
-
| Category | Count | Key Components |
|
|
72
|
-
|----------|-------|---------------|
|
|
73
|
-
| {category} | {count} | {ComponentA}, {ComponentB}, {ComponentC}, ... |
|
|
74
|
-
|
|
75
|
-
**Design system variants:** {primary} (primary), {variant2}, {variant3}
|
|
76
|
-
**Total components:** {unique_count} | **With {variant1}:** {count1} | **With {variant2}:** {count2}
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
- Source: `component_catalog[]` from step 3d extraction
|
|
80
|
-
- Group by `category` field from registry
|
|
81
|
-
- Show top 3-5 component names per category
|
|
82
|
-
- Cite registry file: `[SRC:{registry_file}:L1]`
|
|
83
|
-
- Budget: ~20 lines (same as standard Section 4)
|
|
84
|
-
|
|
85
|
-
#### Section 5 — Key Props (replaces Key Types)
|
|
86
|
-
|
|
87
|
-
```markdown
|
|
88
|
-
## Key Types
|
|
89
|
-
|
|
90
|
-
### {ComponentName}Props
|
|
91
|
-
|
|
92
|
-
| Prop | Type | Default | Required |
|
|
93
|
-
|------|------|---------|----------|
|
|
94
|
-
| {propName} | {type} | {default or —} | {yes/no} |
|
|
95
|
-
|
|
96
|
-
{Repeat for top 5 Props interfaces}
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
- Show only the 5 most-used Props interfaces (by component count or documentation prominence)
|
|
100
|
-
- Full Props details for all components go in Tier 2 reference
|
|
101
|
-
- Budget: ~20 lines (same as standard Section 5)
|
|
102
|
-
|
|
103
|
-
#### Tier 2 — Props Reference (replaces Full API Reference)
|
|
104
|
-
|
|
105
|
-
```markdown
|
|
106
|
-
## Full API Reference
|
|
107
|
-
|
|
108
|
-
### {ComponentName}
|
|
41
|
+
Assembly ordering, the under-300-line Tier-1 budget, and split-body targeting are owned by `assets/compile-assembly-rules.md` (### Assembly Rules).
|
|
109
42
|
|
|
110
|
-
|
|
111
|
-
**Available in:** {variant list}
|
|
112
|
-
**Props:** `{ComponentName}Props`
|
|
113
|
-
|
|
114
|
-
| Prop | Type | Default | Description |
|
|
115
|
-
|------|------|---------|-------------|
|
|
116
|
-
| {prop} | {type} | {default} | {description from JSDoc or —} |
|
|
117
|
-
|
|
118
|
-
**Provenance:** `[AST:{file}:L{line}]`
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
- Organize by component, not by function
|
|
122
|
-
- Each component shows: install command, variant availability, full props table
|
|
123
|
-
- Include JSDoc descriptions for props when available
|
|
124
|
-
- Standard provenance citations apply
|
|
125
|
-
|
|
126
|
-
#### context-snippet.md — Component Library Format
|
|
43
|
+
### Component Library Section Overrides
|
|
127
44
|
|
|
128
|
-
|
|
129
|
-
[{name} v{version}]|root: skills/{name}/
|
|
130
|
-
|IMPORTANT: {name} v{version} — read SKILL.md before writing {name} code. Do NOT rely on training data.
|
|
131
|
-
|install: npx {cli} add <component-id>
|
|
132
|
-
|catalog:{SKILL.md#component-catalog} — {N} components: {category(count), ...}
|
|
133
|
-
|variants: {variant list} — {provider wrapping note if applicable}
|
|
134
|
-
|key-props:{SKILL.md#key-types} — {top props interfaces with key fields}
|
|
135
|
-
|gotchas: {detected gotchas}
|
|
136
|
-
```
|
|
45
|
+
The `component-library` section formats — Component Catalog (§4), Key Props (§5), the Props Reference Tier 2 layout, and the component-library `context-snippet.md` format — are owned by `assets/compile-assembly-rules.md` (### Component Library Assembly Overrides), alongside the `reference-app` and whole-language override sets. This catalog does not restate them (both files load together at compile.md §1).
|
|
137
46
|
|
|
138
47
|
### Provenance Citation Format
|
|
139
48
|
|
|
@@ -181,7 +90,7 @@ Indexed pipe-delimited format for CLAUDE.md managed section (~80-120 tokens per
|
|
|
181
90
|
- **Token budget:** ~80-120 tokens per skill (justified by Vercel's finding that indexed format maintains performance at 80% compression)
|
|
182
91
|
- **T1-now content only** — no T2 annotations in the snippet
|
|
183
92
|
- **Section anchors** (`#quick-start`, `#key-types`) must match actual SKILL.md heading slugs
|
|
184
|
-
- **Version** comes from source detection
|
|
93
|
+
- **Version** comes from source detection, not brief default
|
|
185
94
|
|
|
186
95
|
---
|
|
187
96
|
|
|
@@ -321,7 +230,7 @@ Each reference file includes:
|
|
|
321
230
|
|
|
322
231
|
- `provenance_version`: Schema version. `"2.0"` enables unified single/stack support. Audit reads both v1 (no version field) and v2.
|
|
323
232
|
- `source_library`: Identifies which library an export belongs to. For single skills, defaults to the skill/package name. For stack skills, identifies the constituent library.
|
|
324
|
-
- `integrations`: Stack-only. Describes cross-library integration patterns with their own schema —
|
|
233
|
+
- `integrations`: Stack-only. Describes cross-library integration patterns with their own schema — not shoehorned into entries.
|
|
325
234
|
- `constituents`: Stack-only (compose-mode). Tracks the compose-time snapshot of each source skill for staleness detection. `metadata_hash` enables audit to detect constituent drift without re-reading all constituent files.
|
|
326
235
|
- `file_entries` remains optional — omit when no scripts, assets, or promoted docs exist.
|
|
327
236
|
- Single skills omit `integrations` and `constituents` arrays entirely (not empty arrays).
|
|
@@ -393,6 +302,6 @@ t2_future_count: {N}
|
|
|
393
302
|
- {any warnings from extraction or validation}
|
|
394
303
|
```
|
|
395
304
|
|
|
396
|
-
**Frontmatter — pinned detection contract:** the `t2_future_count` field is the authoritative forward-looking-annotation count for downstream gate checks (e.g. skf-test-skill §2b migration-section rule). Emit **always**, even when 0 — omission is indistinguishable from "no T2-future data" and silently flips the gate into Case 2/3 for a Case-1 skill. `generated` and `forge_tier` mirror the narrative header for consumers that read only the frontmatter. Downstream gate rules
|
|
305
|
+
**Frontmatter — pinned detection contract:** the `t2_future_count` field is the authoritative forward-looking-annotation count for downstream gate checks (e.g. skf-test-skill §2b migration-section rule). Emit **always**, even when 0 — omission is indistinguishable from "no T2-future data" and silently flips the gate into Case 2/3 for a Case-1 skill. `generated` and `forge_tier` mirror the narrative header for consumers that read only the frontmatter. Downstream gate rules parse `t2_future_count` from frontmatter, not prose — prose drift (heading renames, alternate phrasings like "forward-looking annotations") silently breaks grep-based detection.
|
|
397
306
|
|
|
398
307
|
**Description Guard slot:** populated by step 6 §0 (create-skill) and §0 (update-skill) when the guard protocol fires. `Restored: true` indicates that an external tool (typically `skill-check --fix` or `split-body`) rewrote the frontmatter `description` and the guard restored the pre-tool value. When `Restored: false`, leave `Triggering tool`, `Original description preserved`, and `Notes` as `—`. When `Restored: true`, fill all four fields: tool name, whether the original was successfully written back, and a one-sentence note describing what the tool had changed (e.g., "replaced with generic summary", "truncated at 80 chars", "angle-bracket tokens re-introduced"). Downstream test-skill assertions can grep for `Restored: true` to detect unintended tool rewrites without parsing free-form warning prose.
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# tessl Dismissal Rules
|
|
2
2
|
|
|
3
|
-
This file is the **single source of truth** for tessl review findings that Skill Forge expects and must dismiss. Step-06 §6 loads this file, parses the `tessl skill review` JSON output, and cross-references each finding against the rules below. Matches are dismissed with their rationale logged to the evidence report; non-matches surface to the user via §6b.
|
|
4
|
-
|
|
5
|
-
**Why this file exists:** Previously, expected tessl behavior was enumerated as prose in step 6 itself. Each time tessl evolved a scorer or added a new rule, step 6 had to be manually patched and the prose re-read by every execution. This file moves the expected behavior into a structured list with stable rule IDs, rationales, and match criteria — one place to update when tessl changes, one place to audit what SKF expects.
|
|
3
|
+
This file is the **single source of truth** for tessl review findings that Skill Forge expects and must dismiss. Step-06 §6 loads this file, parses the `tessl skill review` JSON output, and cross-references each finding against the rules below. Matches are dismissed with their rationale logged to the evidence report; non-matches surface to the user via §6b. Never embed dismissal logic in step files — update the rules here first and reference them from step 6.
|
|
6
4
|
|
|
7
5
|
---
|
|
8
6
|
|
|
@@ -17,7 +15,7 @@ When parsing tessl output, check these fields against the thresholds below. Viol
|
|
|
17
15
|
| `description_score` (LLM judge %) | `>= 60` | warn | The judge's 0–100 discoverability score, composed of `trigger_term_quality`, `specificity`, `completeness`, and `distinctiveness` sub-scores. A value below 100 while the deterministic `description_field` validator PASSES is a soft discoverability hint (e.g. jargon density), **not** a sanitizer bypass — record a warning and continue. Never halt on the judge percentage alone; the authored brief is the source of truth for the description. |
|
|
18
16
|
| `content_score` | `>= 60` | warn | Two-tier design deliberately duplicates key API data across Tier 1 and Tier 2. Conciseness scorer penalizes this. 60 is the acceptable floor. |
|
|
19
17
|
|
|
20
|
-
**Recovery is gated on the deterministic validator, not the judge percentage.** If tessl emits a `findings[]` entry with rule ID `description_field` (angle-bracket / XML-tag rejection), **attempt recovery first** per rule `description-xml-tags-guarded-upstream` below: re-apply step 5 §2a's `<` → `{` / `>` → `}` substitution in place on the staging SKILL.md frontmatter `description`, then re-run `npx -y tessl skill review <staging-skill-dir>` once. If the re-run clears the `description_field` finding, log `description-recovery: applied ({count} substitutions)` in the evidence report and proceed to normal suggestion handling. If recovery fails, halt with: "Description sanitization recovery failed — step 5 §2a's `<`/`>` → `{`/`}` replacement did not resolve the tessl finding. Investigate the staging SKILL.md frontmatter for non-angle-bracket content that tessl is still rejecting, and patch §2a accordingly. Do not edit the description manually." Do
|
|
18
|
+
**Recovery is gated on the deterministic validator, not the judge percentage.** If tessl emits a `findings[]` entry with rule ID `description_field` (angle-bracket / XML-tag rejection), **attempt recovery first** per rule `description-xml-tags-guarded-upstream` below: re-apply step 5 §2a's `<` → `{` / `>` → `}` substitution in place on the staging SKILL.md frontmatter `description`, then re-run `npx -y tessl skill review <staging-skill-dir>` once. If the re-run clears the `description_field` finding, log `description-recovery: applied ({count} substitutions)` in the evidence report and proceed to normal suggestion handling. If recovery fails, halt with: "Description sanitization recovery failed — step 5 §2a's `<`/`>` → `{`/`}` replacement did not resolve the tessl finding. Investigate the staging SKILL.md frontmatter for non-angle-bracket content that tessl is still rejecting, and patch §2a accordingly. Do not edit the description manually." Do not proceed to §6b user prompt on an unrecovered failure.
|
|
21
19
|
|
|
22
20
|
A `description_score` (LLM judge %) below 100 **without** an accompanying `description_field` finding is **not** a recovery trigger and **not** a halt condition: record `description_judge_score: {n}% (deterministic description_field validator PASSED)` as a warning in the evidence report and continue to suggestion handling. The recover-then-halt path is reserved for the deterministic validator.
|
|
23
21
|
|
|
@@ -25,7 +23,7 @@ A `description_score` (LLM judge %) below 100 **without** an accompanying `descr
|
|
|
25
23
|
|
|
26
24
|
## Suggestion Dismissal Rules
|
|
27
25
|
|
|
28
|
-
Each rule below describes a tessl suggestion that Skill Forge expects and dismisses automatically. For each `judge_suggestion` in tessl output, check it against these rules in order. If any rule matches, record the dismissal in the evidence report (`rule_id`, `rationale`) and do
|
|
26
|
+
Each rule below describes a tessl suggestion that Skill Forge expects and dismisses automatically. For each `judge_suggestion` in tessl output, check it against these rules in order. If any rule matches, record the dismissal in the evidence report (`rule_id`, `rationale`) and do not apply the suggestion. If no rule matches, the suggestion is novel and must surface to the user in §6b.
|
|
29
27
|
|
|
30
28
|
### Rule: `remove-manual-markers`
|
|
31
29
|
|
|
@@ -105,11 +103,4 @@ The recovery path makes the skill shippable when a downstream tool (`skill-check
|
|
|
105
103
|
|
|
106
104
|
## Evolving This List
|
|
107
105
|
|
|
108
|
-
When tessl
|
|
109
|
-
|
|
110
|
-
1. **Add a new rule section** above with `Rule:`, `Scorer:`, `Match criteria`, `Rationale`, `Action`.
|
|
111
|
-
2. **Link the rationale** to the concrete SKF design principle it protects (two-tier design, MANUAL markers, sanitization, split-body preservation, etc.). A rationale without a design-principle link is a smell.
|
|
112
|
-
3. **Keep score thresholds above current production floors.** Do not lower them to suppress real regressions.
|
|
113
|
-
4. **Never embed dismissal logic in step files.** If step 6 needs updated behavior, update this file first and reference it from step 6.
|
|
114
|
-
|
|
115
|
-
This file is load-bearing: step 6 §6 has no other source of truth for expected tessl behavior.
|
|
106
|
+
When tessl changes or an SKF design decision shifts, add a new rule section above (`Rule:` / `Scorer:` / `Match criteria` / `Rationale` / `Action`), link each rationale to the concrete SKF design principle it protects (two-tier design, MANUAL markers, sanitization, split-body preservation — a rationale without such a link is a smell), and keep score thresholds at or above current production floors — never lower them to suppress real regressions.
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# DO NOT EDIT -- overwritten on every update.
|
|
2
2
|
#
|
|
3
3
|
# Workflow customization surface for skf-create-skill.
|
|
4
|
+
# Team overrides: _bmad/custom/skf-create-skill.toml (under {project-root})
|
|
5
|
+
# Personal overrides: _bmad/custom/skf-create-skill.user.toml (under {project-root})
|
|
4
6
|
|
|
5
7
|
[workflow]
|
|
6
8
|
|
|
@@ -33,3 +35,14 @@ activation_steps_append = []
|
|
|
33
35
|
persistent_facts = [
|
|
34
36
|
"file:{project-root}/**/project-context.md",
|
|
35
37
|
]
|
|
38
|
+
|
|
39
|
+
# Pipeline-integration hook invoked after the final report (step 8) and the
|
|
40
|
+
# result JSON / metadata.json are finalized. The command is called as:
|
|
41
|
+
# <on_complete> --result-path=<{forge_version}/create-skill-result-latest.json>
|
|
42
|
+
# Useful for Slack notifications, dashboard ingest, CI hooks, or chaining a
|
|
43
|
+
# downstream skill (TS test-skill, EX export). Failures are logged to
|
|
44
|
+
# workflow_warnings[] but never fail the workflow.
|
|
45
|
+
#
|
|
46
|
+
# Empty string = no-op (default).
|
|
47
|
+
|
|
48
|
+
on_complete = ""
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Overview
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Loaded on demand when step 3's `### 2a. Discovered Authoritative Files Protocol` sub-step runs.
|
|
6
6
|
|
|
7
7
|
**Skip this protocol entirely if `source_type: "docs-only"`** — there is no source tree to scan.
|
|
8
8
|
|
|
@@ -59,7 +59,7 @@ This protocol detects such files, prompts the user, and records the decision in
|
|
|
59
59
|
- **`pre_decided[]` with `prior_action: "skipped"`** — user previously declined. Do nothing. Move on.
|
|
60
60
|
- **`unresolved[]`** — proceed to step 3 below (user prompt).
|
|
61
61
|
|
|
62
|
-
3. **Prompt.** Present each `unresolved[]` candidate to the user. Use the helper's `preview`, `size_bytes`, `line_count`, and `excluded_by_pattern` fields verbatim
|
|
62
|
+
3. **Prompt.** Present each `unresolved[]` candidate to the user. Use the helper's `preview`, `size_bytes`, `line_count`, and `excluded_by_pattern` fields verbatim so the prompt reports facts rather than recomputing them:
|
|
63
63
|
|
|
64
64
|
```
|
|
65
65
|
**Discovered authoritative file excluded by brief scope**
|
|
@@ -84,7 +84,7 @@ This protocol detects such files, prompts the user, and records the decision in
|
|
|
84
84
|
5. **Apply decision:**
|
|
85
85
|
|
|
86
86
|
- **[P] Promote:**
|
|
87
|
-
1. **Do
|
|
87
|
+
1. **Do not add the path to the filtered file list from §2.** Authoritative documentation files are not code — they must not go through the AST extraction pipeline in §4, which would silently produce no exports (ghost entries). Instead, add the path to a new in-context list `promoted_docs[]` with `{path, heuristic, size_bytes, line_count, content_hash}`. Compute the SHA-256 content hash of the file now.
|
|
88
88
|
2. Append to `brief.scope.include`: add the exact `candidate.path` as a literal glob (no wildcards — the amendment targets this specific file). This write ensures that a re-run of `skf-create-skill` against the amended brief sees the path in scope and skips re-prompting.
|
|
89
89
|
3. Append to `brief.scope.amendments[]` a new entry with `action: "promoted"`, `path: candidate.path`, `reason: {user-provided one-sentence reason or auto-generated "authoritative AI docs — matched heuristic {basename}"}`, `heuristic: {basename}`, `date: {today ISO}`, `workflow: "skf-create-skill"`.
|
|
90
90
|
4. **Write the amended brief back to disk immediately** at `{forge_data_folder}/{skill_name}/skill-brief.yaml`. Immediate write (not deferred to step 7) ensures a crashed run still leaves the amendment recorded. Preserve all other brief fields and formatting. **Use atomic write + backup:** before writing, copy the original brief to `{forge_data_folder}/{skill_name}/skill-brief.yaml.bak` (overwriting any prior `.bak` — the most recent pre-amendment snapshot is the useful one). Then pipe the amended YAML through the shared atomic writer so a crash mid-write cannot corrupt the brief:
|
|
@@ -105,7 +105,7 @@ This protocol detects such files, prompts the user, and records the decision in
|
|
|
105
105
|
5. Display: "**Promoted `{path}`** — tracked as documentation file, amendment recorded."
|
|
106
106
|
|
|
107
107
|
- **[S] Skip:**
|
|
108
|
-
1. Do
|
|
108
|
+
1. Do not modify `scope.include` or `scope.exclude`.
|
|
109
109
|
2. Append to `brief.scope.amendments[]` a new entry with `action: "skipped"`, `path: candidate.path`, `reason: {user-provided reason or auto-generated "user declined promotion at create-skill §2a"}`, `heuristic: {basename}`, `date: {today ISO}`, `workflow: "skf-create-skill"`.
|
|
110
110
|
3. **Write the amended brief back to disk** so future runs do not re-prompt. Use the same backup-then-atomic-write pattern as the [P] Promote path (copy to `skill-brief.yaml.bak` first, then pipe through `skf-atomic-write.py write --target {brief_path}`).
|
|
111
111
|
4. Display: "**Skipped `{path}`** — decision recorded in amendments."
|
|
@@ -124,11 +124,11 @@ This protocol detects such files, prompts the user, and records the decision in
|
|
|
124
124
|
|
|
125
125
|
## How promoted docs reach the provenance map
|
|
126
126
|
|
|
127
|
-
Promoted docs do
|
|
127
|
+
Promoted docs do not flow through §4 code extraction. Instead:
|
|
128
128
|
|
|
129
129
|
1. §2a populates the in-context `promoted_docs[]` list with content hashes.
|
|
130
130
|
2. **Step-05 §6** (provenance-map assembly) reads `promoted_docs[]` and emits one `file_entries[]` entry per promoted doc with `file_type: "doc"`, `extraction_method: "promoted-authoritative"`, `confidence: "T1-low"`, and the pre-computed `content_hash`.
|
|
131
|
-
3. **Step-07 §2** does
|
|
131
|
+
3. **Step-07 §2** does not copy doc files into the skill package (unlike scripts and assets). The source file remains at its original path; only the provenance map tracks it. Future audit and update workflows compare against this tracking entry via content hash — no file copy is required because the intent is drift detection on the *source*, not bundling documentation into the skill output.
|
|
132
132
|
|
|
133
133
|
**Re-running `skf-create-skill`** reads the amended brief. Files with `action: "promoted"` amendments already appear in `scope.include`, but §2a still runs — it detects the file is in scope AND has an existing amendment, and takes the "pre-decided" silent path. The `promoted_docs[]` list is rebuilt on each run by scanning amendments with `action: "promoted"` (this is the deterministic replay path).
|
|
134
134
|
|
|
@@ -137,6 +137,6 @@ Promoted docs do NOT flow through §4 code extraction. Instead:
|
|
|
137
137
|
Zero code changes required in consumer workflows:
|
|
138
138
|
|
|
139
139
|
- **`skf-update-skill`** reads `provenance-map.json`. Promoted docs appear as `file_entries[]` entries. Update-skill Category D (script/asset file changes) iterates `file_entries` and compares content hashes — this works identically for `file_type: "doc"` entries, giving drift detection for free.
|
|
140
|
-
- **`skf-audit-skill`**
|
|
140
|
+
- **`skf-audit-skill`** scans files from `provenance-map.json`. The re-index builds its list from `entries[].source_file ∪ file_entries[].source_file`, so promoted doc paths are naturally included in the audit scan.
|
|
141
141
|
|
|
142
142
|
The brief is the single source of truth for authored scope intent. The provenance map is the single source of truth for extracted state. `scope.amendments[]` is the bridge that records when those two intentionally diverged. `promoted_docs[]` is the in-memory handoff from §2a to step 5 §6; it is not persisted — the persisted form is the `file_entries[]` list in provenance-map.json.
|
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
nextStepFile: 'step-doc-sources.md'
|
|
3
3
|
skillSectionsData: 'assets/skill-sections.md'
|
|
4
4
|
assemblyRulesData: 'assets/compile-assembly-rules.md'
|
|
5
|
+
# Resolve `{renderMetadataStatsHelper}` by probing `{renderMetadataStatsProbeOrder}`
|
|
6
|
+
# in order (installed SKF module path first, src/ dev-checkout fallback); first
|
|
7
|
+
# existing path wins. HALT if neither resolves — the metadata `stats` block and
|
|
8
|
+
# `confidence_distribution` are computed values that must not be hand-binned
|
|
9
|
+
# (the historical 147 ≠ 59 miscount lived exactly here).
|
|
10
|
+
renderMetadataStatsProbeOrder:
|
|
11
|
+
- '{project-root}/_bmad/skf/shared/scripts/skf-render-metadata-stats.py'
|
|
12
|
+
- '{project-root}/src/shared/scripts/skf-render-metadata-stats.py'
|
|
5
13
|
---
|
|
6
14
|
|
|
7
15
|
<!-- Config: communicate in {communication_language}. -->
|
|
@@ -44,11 +52,11 @@ This is the `<staging-skill-dir>` referenced by step 6 (`npx skill-check check`,
|
|
|
44
52
|
**When assembling function signatures, parameter lists, and return types in any SKILL.md section or reference file:**
|
|
45
53
|
|
|
46
54
|
- **T1 provenance-map entries (AST-extracted) are authoritative** for: function name, parameter names, parameter types, parameter order, return type, and optionality markers (e.g., `?`, `Optional`, `= default`).
|
|
47
|
-
- **T2 (QMD-enriched) and T3 (doc-derived) sources may
|
|
55
|
+
- **T2 (QMD-enriched) and T3 (doc-derived) sources may add** contextual descriptions, usage notes, behavioral documentation, and examples to function entries, but must not replace structural signature data from T1 entries.
|
|
48
56
|
- **On conflict:** If a T2/T3 source provides a different signature than the T1 extraction for the same export (e.g., different parameter count, different types, missing `Partial<>` wrapper), keep the T1 signature and log a warning in the evidence report: "Signature conflict for `{export_name}`: T1 shows `{t1_signature}`, T2/T3 shows `{other_signature}`. T1 used as authoritative."
|
|
49
57
|
- **`signature_source` field:** Record `signature_source: "T1" | "T1-low" | "T2" | "T3"` in each provenance-map entry to indicate the highest-confidence tier that contributed the structural signature data (params, return_type). This enables test-skill to verify signature provenance.
|
|
50
58
|
|
|
51
|
-
This rule applies to
|
|
59
|
+
This rule applies to every section including Tier 1 Key API Summary, Tier 2 Full API Reference, and Section 4b Migration & Deprecation Warnings.
|
|
52
60
|
|
|
53
61
|
### 2. Build SKILL.md Content
|
|
54
62
|
|
|
@@ -62,17 +70,11 @@ Assemble each section in order using the assembly rules data file (`{assemblyRul
|
|
|
62
70
|
|
|
63
71
|
**Why unconditional?** Both `skill-check`'s `description_field` validator and `tessl`'s deterministic description check parse the frontmatter `description` as a raw string — they reject any `<` or `>` regardless of whether the content is inside a backtick span or a generic expression. The previous rule exempted backticked content on the assumption that backticks protect from XML-tag parsing, but that assumption is false for these validators: a backticked TypeScript generic like `` `Meta<typeof X>` `` still fails tessl's check because tessl reads the raw string before markdown parsing. Unconditional replacement guarantees no angle brackets reach either validator.
|
|
64
72
|
|
|
65
|
-
**Coverage examples** (all handled by the same `<`/`>` → `{`/`}` replacement):
|
|
66
|
-
|
|
67
|
-
- Standalone placeholders: `<name>` → `{name}`, `<component-id>` → `{component-id}` — curly braces are the standard placeholder notation in prose and render cleanly.
|
|
68
|
-
- Backticked TypeScript / C++ / Rust generics: `` `Meta<typeof X>` `` → `` `Meta{typeof X}` ``, `` `Array<T>` `` → `` `Array{T}` ``, `` `Vec<u8>` `` → `` `Vec{u8}` `` — readable approximations that preserve the author's intent for code-ish fragments.
|
|
69
|
-
- Any other angle-bracket content, whether inside backticks or bare, is also rewritten.
|
|
70
|
-
|
|
71
73
|
**Scope:** This rule applies **only** to the frontmatter `description` field. Body content, code examples, reference files, and assembly-rule documents retain their original angle brackets — they are parsed through the markdown AST where backticks do protect content.
|
|
72
74
|
|
|
73
75
|
Record the count of substitutions in context as `description_sanitizations: {count}` for the evidence report.
|
|
74
76
|
|
|
75
|
-
|
|
77
|
+
If a downstream tool re-introduces angle brackets into the description, step 6 §6 recovers via `description-xml-tags-guarded-upstream` in `assets/tessl-dismissal-rules.md`.
|
|
76
78
|
|
|
77
79
|
### 3. Build context-snippet.md Content
|
|
78
80
|
|
|
@@ -102,23 +104,30 @@ Following the structure from the skill-sections data file:
|
|
|
102
104
|
- Set `generation_date` to current ISO-8601 timestamp
|
|
103
105
|
- Set `source_commit` from resolved source (if available)
|
|
104
106
|
- Set `source_ref` from resolved source ref (tag name, branch, or `HEAD`; null if unavailable)
|
|
105
|
-
- Set `scope_type` from the brief's `scope.type` value verbatim (`full-library`, `specific-modules`, `public-api`, `component-library`, `reference-app`, or `docs-only`). **Always emit this field.** `skf-test-skill` keys reference-app handling on `metadata.json.scope_type == "reference-app"` — both the scoring redistribution (Signature Accuracy / Type Coverage marked N/A) and the coverage-check §4b count-coherence skip. Omitting it silently mis-scores a reference-app skill as a library (zero-export barrel HALT or false metadata-drift findings)
|
|
106
|
-
-
|
|
107
|
-
|
|
108
|
-
|
|
107
|
+
- Set `scope_type` from the brief's `scope.type` value verbatim (`full-library`, `specific-modules`, `public-api`, `component-library`, `reference-app`, or `docs-only`). **Always emit this field.** `skf-test-skill` keys reference-app handling on `metadata.json.scope_type == "reference-app"` — both the scoring redistribution (Signature Accuracy / Type Coverage marked N/A) and the coverage-check §4b count-coherence skip. Omitting it silently mis-scores a reference-app skill as a library (zero-export barrel HALT or false metadata-drift findings). The value is informational for the other scope types (consumers only branch on `reference-app`), but emit it for all so the producer/consumer contract holds.
|
|
108
|
+
- **Compute the `stats` block and `confidence_distribution` deterministically** with `{renderMetadataStatsHelper}` (resolve from `{renderMetadataStatsProbeOrder}`; first existing path wins). The helper owns all the arithmetic — binning each provenance entry once by its `signature_source` tier, summing the bins, and computing every coverage ratio — and returns the finished `stats` + `confidence_distribution` objects to write into `metadata.json` verbatim. Run `uv run {renderMetadataStatsHelper} --help` for the full contract. You supply only the judgment payload below.
|
|
109
|
+
|
|
110
|
+
**Judgment payload (what you decide — passed as JSON on stdin):**
|
|
111
|
+
- `exports_public_api`: count of exports from public entry points (`__init__.py`, `index.ts`, `lib.rs`, or equivalent) — derive this from step 3's entry-point validation (section 4b), not from the provenance-map entry count (which may be incomplete if extraction patterns missed some export types)
|
|
109
112
|
- `exports_internal`: count of all other non-underscore-prefixed exports (internal modules, helpers, adapters)
|
|
110
|
-
- `
|
|
111
|
-
- `
|
|
112
|
-
- `total_coverage`: `exports_documented / exports_total` (may be low for large codebases — this is expected; `null` if `exports_total` is 0)
|
|
113
|
-
- `effective_denominator` (**optional** — emit only for stratified-scope monorepo packages): the count of public exports from files matched by the brief's authoring-surface globs, filtered by `scope.exclude`, resolved against `source_path`. **Prefer `scope.tier_a_include` when the brief supplies it** — that narrow list represents the authoring surface the brief intends to document; resolve its globs across `source_path` and count the union of **named exports** — items reachable from the language's public entry-point barrel (`lib.rs` `pub use`, `index.ts` / `index.js` re-exports, `__init__.py` exports), where a type counts **once** with its methods and impl-block members rolling up under it (count a `pub fn` only when it is a free function reachable from the barrel, never a method on an already-counted type). **Otherwise use `scope.include`** — the coarse list. This counting unit matches what `skf-test-skill` re-derives on the consumer side (`coverage-check.md` §2c excludes `kind: "method"` from `documented_set`), so the producer- and test-side denominators stay aligned; without it, a type-heavy API (a few handle types carrying hundreds of methods) inflates the denominator by an order of magnitude and auto-fails the coverage gate. This is the coverage denominator `skf-test-skill` uses when the package is a curated subset of a multi-package repository, so it must match the brief's authoring intent. Compute when ALL of the following hold:
|
|
113
|
+
- `scripts` / `assets`: the `scripts_inventory` / `assets_inventory` arrays (or `[]` when empty) — the helper sets `stats.scripts_count` / `stats.assets_count` from their lengths
|
|
114
|
+
- `effective_denominator` (**optional** — include in the helper's judgment payload only for stratified-scope monorepo packages): the count of public exports from files matched by the brief's authoring-surface globs, filtered by `scope.exclude`, resolved against `source_path`. **Prefer `scope.tier_a_include` when the brief supplies it** — that narrow list represents the authoring surface the brief intends to document; resolve its globs across `source_path` and count the union of **named exports** — items reachable from the language's public entry-point barrel (`lib.rs` `pub use`, `index.ts` / `index.js` re-exports, `__init__.py` exports), where a type counts **once** with its methods and impl-block members rolling up under it (count a `pub fn` only when it is a free function reachable from the barrel, never a method on an already-counted type). **Otherwise use `scope.include`** — the coarse list. This counting unit matches what `skf-test-skill` re-derives on the consumer side (`coverage-check.md` §2c excludes `kind: "method"` from `documented_set`), so the producer- and test-side denominators stay aligned; without it, a type-heavy API (a few handle types carrying hundreds of methods) inflates the denominator by an order of magnitude and auto-fails the coverage gate. This is the coverage denominator `skf-test-skill` uses when the package is a curated subset of a multi-package repository, so it must match the brief's authoring intent. Compute when ALL of the following hold:
|
|
114
115
|
1. The source is a monorepo (detected via `packages/` layout, `workspaces` field in root `package.json`, `lerna.json`, `rush.json`, `nx.json`, or Cargo `[workspace]`).
|
|
115
116
|
2. `scope.type` is not `full-library` (and not `reference-app` — see carve-out below), AND the resolved include list (`tier_a_include` if present, else `scope.include`) lists a curated file/directory subset rather than the full workspace.
|
|
116
117
|
3. `scope.notes` is present and documents the stratification strategy (e.g., a tiered A/B/C plan) — this serves as the intent marker confirming the subset is by design.
|
|
117
118
|
|
|
118
|
-
Otherwise omit the
|
|
119
|
+
Otherwise omit it from the payload entirely — when absent, `skf-test-skill` falls back to `exports_public_api`. See `skf-test-skill` `references/source-access-protocol.md` §Source API Surface Definition ("Stratified-scope monorepo packages") for the test-side consumption rules.
|
|
119
120
|
|
|
120
121
|
**Reference-app carve-out:** never emit `effective_denominator` for `scope.type: "reference-app"`, even when the three conditions above are literally satisfied (a reference-app-in-monorepo matches all of them). A reference app's coverage basis is `pattern_surfaces_documented`, not library exports — see the Reference-App stats semantics in `assets/compile-assembly-rules.md`.
|
|
121
|
-
-
|
|
122
|
+
- **Shape:** pass `--shape reference-app` or `--shape stack` when the matching assembly-rules override applies (default `library`). For a reference app, also put `pattern_surfaces_documented` (the Pattern Surface row count) in the payload — the helper uses it as `exports_documented`, emits `stats.pattern_surfaces_documented`, and refuses to emit `effective_denominator`; the distribution then sums to the per-citation count, not to `exports_documented`. For a stack, put the own-barrel `exports_documented` (usually `0`) in the payload; the distribution sums to the cited-constituent count.
|
|
123
|
+
- **Invoke** — stage `provenance-map.json` (§6) first, since the helper reads its `entries[]`:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
echo '{"exports_public_api": {N}, "exports_internal": {M}, "scripts": {scripts_inventory-or-[]}, "assets": {assets_inventory-or-[]}}' \
|
|
127
|
+
| uv run {renderMetadataStatsHelper} <staging-skill-dir>/provenance-map.json
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Write the returned `stats` and `confidence_distribution` verbatim. The helper derives `exports_documented` (the documented-export count = provenance `entries[]` count), `exports_total` = `exports_public_api` + `exports_internal`, `public_api_coverage` = documented / public_api (`null` if public_api is 0), `total_coverage` = documented / total (`null` if total is 0), and bins `confidence_distribution.{t1, t1_low, t2, t3}` by each entry's `signature_source` — **each entry counted exactly once**, so the four bins provably sum to the documented-export count. This structurally prevents the recurring miscount where binning ~8 T2 annotations + ~80 T3 doc items on top of 59 exports produced a distribution summing to 147 ≠ 59 (`skf-test-skill` coverage-check §4b flags that sum as an internal-consistency defect). If the helper reports `coherence.ok: false`, some provenance entries carry a missing/unrecognized `signature_source` (or a file-entry count disagrees) — fix the provenance map, do not hand-edit the stats.
|
|
122
131
|
- Set `description` from the SKILL.md frontmatter `description` field (already assembled in section 2)
|
|
123
132
|
- Set `language` from source analysis (e.g., `"typescript"`, `"python"`) — use the primary language of the entry point file
|
|
124
133
|
- Set `ast_node_count` from extraction stats if ast-grep was used (Forge/Deep tier), otherwise omit
|
|
@@ -138,7 +147,7 @@ Following the structure from the skill-sections data file:
|
|
|
138
147
|
3. `"unknown"` (final fallback — add a warning to the evidence report)
|
|
139
148
|
Note: QMD is a Bun/Node package (`@tobilu/qmd`). Install via `bun install -g @tobilu/qmd`.
|
|
140
149
|
- Store `commit_short` = first 8 characters of `source_commit` (or `"unknown"` if unavailable) for use in step 8 report.
|
|
141
|
-
- If `scripts_inventory` is non-empty, populate `scripts[]` array
|
|
150
|
+
- If `scripts_inventory` is non-empty, populate the `scripts[]` array (per-file `{file, purpose, source_file, confidence}` rows). If `assets_inventory` is non-empty, populate the `assets[]` array. Omit the `scripts[]` / `assets[]` arrays entirely when their inventory is empty — `stats.scripts_count` / `stats.assets_count` were already set by `{renderMetadataStatsHelper}` from the `scripts` / `assets` payload you passed it (0 when empty).
|
|
142
151
|
|
|
143
152
|
### 5. Build references/ Content
|
|
144
153
|
|
|
@@ -158,7 +167,7 @@ One entry per extracted export: export_name, export_type, params[] (typed string
|
|
|
158
167
|
|
|
159
168
|
- `scripts_inventory` → `file_type: "script"`, `extraction_method: "file-copy"`, stored in `{skill_package}/scripts/` by step 7
|
|
160
169
|
- `assets_inventory` → `file_type: "asset"`, `extraction_method: "file-copy"`, stored in `{skill_package}/assets/` by step 7
|
|
161
|
-
- `promoted_docs` (from step 3 §2a) → `file_type: "doc"`, `extraction_method: "promoted-authoritative"`, **
|
|
170
|
+
- `promoted_docs` (from step 3 §2a) → `file_type: "doc"`, `extraction_method: "promoted-authoritative"`, **not** copied into the skill package by step 7. The source file stays at its original path; only the provenance tracking entry is written. `content_hash` was pre-computed by §2a.
|
|
162
171
|
|
|
163
172
|
Each `file_entries[]` row has the same shape regardless of `file_type`: `{file_name, file_type, source_file, content_hash, confidence, extraction_method}`. See `{skillSectionsData}` for full schema and the canonical list of `file_type` values.
|
|
164
173
|
|
|
@@ -166,33 +175,11 @@ Each `file_entries[]` row has the same shape regardless of `file_type`: `{file_n
|
|
|
166
175
|
|
|
167
176
|
Compilation audit trail: generation date, forge tier, source info, tool versions, extraction summary (files/exports/confidence), warnings. For validation-specific fields (Schema, Body, Security, Content Quality, tessl, Metadata), insert the placeholder text `[PENDING — populated by step 6]`. Step-06 will replace these placeholders with actual results. See `{skillSectionsData}` for full template. Use the same `{skf_version}` value resolved in section 4 when populating the Tool Versions block.
|
|
168
177
|
|
|
169
|
-
**Frontmatter — pinned fields
|
|
170
|
-
|
|
171
|
-
**Auto-Decisions section (headless buffer flush):** read the in-context `headless_decisions[]` list (populated by step 1 tier-override handling, step 2 ecosystem gate, and any future step that auto-resolves a gate under `{headless_mode}`). Emit an `## Auto-Decisions` section with one row per entry:
|
|
172
|
-
|
|
173
|
-
```
|
|
174
|
-
## Auto-Decisions
|
|
175
|
-
|
|
176
|
-
| Step | Gate | Decision | Rationale | Timestamp |
|
|
177
|
-
|------|------|----------|-----------|-----------|
|
|
178
|
-
| {step} | {gate} | {decision}{value?} | {rationale} | {timestamp} |
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
If `headless_decisions[]` is empty, emit the section header with a single line: `No auto-decisions — workflow ran interactively (or all gates had no match to auto-resolve).` This guarantees the section is always present so reviewers can tell "zero auto-decisions" apart from "section missing".
|
|
182
|
-
|
|
183
|
-
### 8. Menu Handling Logic
|
|
184
|
-
|
|
185
|
-
**Auto-proceed step — no user interaction.**
|
|
186
|
-
|
|
187
|
-
After all content is assembled in context and written to the staging directory, immediately load, read entire file, then execute `{nextStepFile}`.
|
|
188
|
-
|
|
189
|
-
#### EXECUTION RULES:
|
|
178
|
+
**Frontmatter — pinned fields:** emit YAML frontmatter at the top of `evidence-report.md` with at minimum `skill_name`, `generated`, `forge_tier`, and `t2_future_count`. Compute `t2_future_count` as the count of forward-looking (T2-future) temporal annotations in the enrichment data produced by step 4 (`qmd query` + temporal classification). **Emit `t2_future_count: 0` when no T2-future annotations exist** — omission is indistinguishable from "no data" for downstream consumers and would silently flip the skf-test-skill §2b/§5b migration-section gate into Case 2/3 for a Case-1 skill. This frontmatter is the authoritative detection contract — `migration-section-rules.md` Case Rules parse it deterministically rather than grepping prose.
|
|
190
179
|
|
|
191
|
-
- This is
|
|
192
|
-
- All content must be both in context and in `_bmad-output/{skill-name}/` — no final files in `skills/` or `forge-data/` yet
|
|
193
|
-
- Proceed directly to validation after assembly is complete
|
|
180
|
+
**Auto-Decisions section (render from the durable sink):** render the `## Auto-Decisions` section into `evidence-report.md` from the **union of the on-disk auto-decision sink** (`{sidecar_path}/auto-decisions.jsonl`, established at step 1 §3 and appended to on every gate landing) **and the in-context `headless_decisions[]` buffer** — read the sink's JSON lines, union them with the buffer keyed on `step`+`gate` so nothing is duplicated or dropped, and emit one row per entry in the table format documented in step 6 §8. The sink is authoritative: on a long component-library run the in-context buffer may have compacted across the token-heavy step 3→5 extraction window, but the sink carries every decision written as it landed (step 1 tier-override, step 2 ecosystem gate, step 3 zero-exports, step 3d component-extraction gates). This step is the first point `evidence-report.md` is written to disk (staging dir, §8 below). Exactly one gate can still fire after this step — step 6 §6b (the tessl-suggestions gate) — and step 6 §8 re-reconciles idempotently. If the union is empty (no decision has fired), emit the section with the single line `No auto-decisions — workflow ran interactively (or all gates had no match to auto-resolve).` — step 6 §8 replaces that line if a later decision lands.
|
|
194
181
|
|
|
195
|
-
|
|
182
|
+
### 8. Auto-Proceed
|
|
196
183
|
|
|
197
|
-
|
|
184
|
+
No user interaction. Once all content is assembled in context and written to the staging directory `_bmad-output/{skill-name}/` (no final files in `skills/` or `forge-data/` yet), load `{nextStepFile}`, read it fully, then execute it. `extraction-rules.yaml` is generated by step 7 from extraction data — do not create it here.
|
|
198
185
|
|
|
@@ -19,7 +19,7 @@ When `scope.type: "component-library"`, perform specialized extraction that trea
|
|
|
19
19
|
|
|
20
20
|
## MANDATORY SEQUENCE
|
|
21
21
|
|
|
22
|
-
**Prerequisite — §2a already ran.** Step-03 executes `§2a Discovered Authoritative Files Protocol` before delegating to this file. Any promoted authoritative files (`llms.txt`, `AGENTS.md`, etc.) are tracked in the `promoted_docs[]` context list and will be written to `file_entries[]` with `file_type: "doc"` by step 5 §6 — they do
|
|
22
|
+
**Prerequisite — §2a already ran.** Step-03 executes `§2a Discovered Authoritative Files Protocol` before delegating to this file. Any promoted authoritative files (`llms.txt`, `AGENTS.md`, etc.) are tracked in the `promoted_docs[]` context list and will be written to `file_entries[]` with `file_type: "doc"` by step 5 §6 — they do not appear in the filtered file list that was passed into this step, so Phase 1 demo exclusion below only operates on code files. No special handling is required in this file for promoted docs. See step 3 §2a for the full flow.
|
|
23
23
|
|
|
24
24
|
### Phase 1: Demo/Example Exclusion
|
|
25
25
|
|
|
@@ -42,7 +42,7 @@ Before extraction, identify and exclude demo/example files to avoid inflating ex
|
|
|
42
42
|
|
|
43
43
|
Confirm exclusion? [Y/n] Or adjust patterns:"
|
|
44
44
|
|
|
45
|
-
**GATE [default: Y]** — if `{headless_mode}` is true: auto-confirm the auto-detected exclusion patterns, log "headless: auto-confirm demo/example exclusion ({N} files, {M} directories)", and append `{step: "component-extraction", gate: "demo-exclusion", decision: "Y", value: "{N} files / {M} dirs", rationale: "headless mode — auto-detected demo patterns accepted", timestamp: {ISO}}` to `headless_decisions[]`
|
|
45
|
+
**GATE [default: Y]** — if `{headless_mode}` is true: auto-confirm the auto-detected exclusion patterns, log "headless: auto-confirm demo/example exclusion ({N} files, {M} directories)", and append `{step: "component-extraction", gate: "demo-exclusion", decision: "Y", value: "{N} files / {M} dirs", rationale: "headless mode — auto-detected demo patterns accepted", timestamp: {ISO}}` to `headless_decisions[]` and, the moment it lands, append the same object as a JSON line to the durable audit sink `{sidecar_path}/auto-decisions.jsonl` (the on-landing append established at step 1 §3) — the sink feeds the evidence-report `## Auto-Decisions` table at step 5 §7 and step 6 §8. Then proceed without waiting.
|
|
46
46
|
|
|
47
47
|
Wait for user response (interactive only). Apply confirmed patterns to the exclude list. Record `demo_files_excluded: {count}` in context.
|
|
48
48
|
|
|
@@ -85,7 +85,7 @@ Sample entries:
|
|
|
85
85
|
|
|
86
86
|
Is this the component registry? [Y/n] Or provide the correct path:"
|
|
87
87
|
|
|
88
|
-
**GATE [default: Y]** — if `{headless_mode}` is true AND `score >= 7` (high-confidence candidate): auto-confirm the registry candidate, log "headless: auto-confirm registry candidate `{path}` (score {score}/9)", and append `{step: "component-extraction", gate: "registry-confirm", decision: "Y", value: "{path} score={score}/9", rationale: "headless mode — high-confidence registry candidate auto-accepted", timestamp: {ISO}}` to `headless_decisions[]
|
|
88
|
+
**GATE [default: Y]** — if `{headless_mode}` is true AND `score >= 7` (high-confidence candidate): auto-confirm the registry candidate, log "headless: auto-confirm registry candidate `{path}` (score {score}/9)", and append `{step: "component-extraction", gate: "registry-confirm", decision: "Y", value: "{path} score={score}/9", rationale: "headless mode — high-confidence registry candidate auto-accepted", timestamp: {ISO}}` to `headless_decisions[]` and, the moment it lands, append the same object as a JSON line to the durable audit sink `{sidecar_path}/auto-decisions.jsonl` (the on-landing append established at step 1 §3). If `score < 7` in headless mode, auto-reject the candidate (treat as "no registry found"), log "headless: auto-reject low-confidence registry candidate (score {score}/9) — below auto-accept threshold 7", record the decision the same way (buffer + sink, `decision: "reject-low-score"`), and fall through to the "no registry found" branch below. Confidence threshold 7 matches the minimum score the heuristic considers "probable enough to risk" without human eyes.
|
|
89
89
|
|
|
90
90
|
Wait for user response (interactive only).
|
|
91
91
|
|
|
@@ -95,7 +95,7 @@ Wait for user response (interactive only).
|
|
|
95
95
|
- **[P]** Provide the registry file path
|
|
96
96
|
- **[S]** Skip registry — proceed with standard props-first extraction only"
|
|
97
97
|
|
|
98
|
-
**GATE [default: S]** — if `{headless_mode}` is true: auto-select [S] Skip (props-first extraction without registry), log "headless: no registry detected, auto-skip to props-first extraction (no path was provided in brief.scope.registry_path)", and append `{step: "component-extraction", gate: "provide-or-skip-registry", decision: "S", rationale: "headless mode — no human to provide registry path", timestamp: {ISO}}` to `headless_decisions[]
|
|
98
|
+
**GATE [default: S]** — if `{headless_mode}` is true: auto-select [S] Skip (props-first extraction without registry), log "headless: no registry detected, auto-skip to props-first extraction (no path was provided in brief.scope.registry_path)", and append `{step: "component-extraction", gate: "provide-or-skip-registry", decision: "S", rationale: "headless mode — no human to provide registry path", timestamp: {ISO}}` to `headless_decisions[]` and, the moment it lands, append the same object as a JSON line to the durable audit sink `{sidecar_path}/auto-decisions.jsonl` (the on-landing append established at step 1 §3). The default is `[S]` rather than `[P]` because providing a path requires user input that headless cannot supply; skipping degrades gracefully to a smaller but valid extraction.
|
|
99
99
|
|
|
100
100
|
Wait for user response (interactive only).
|
|
101
101
|
|
|
@@ -160,7 +160,7 @@ constraints:
|
|
|
160
160
|
|
|
161
161
|
Also run `export const $NAME` patterns for arrow function components.
|
|
162
162
|
|
|
163
|
-
For each component export: record name, source file, line number. Do
|
|
163
|
+
For each component export: record name, source file, line number. Do not document the function signature in detail (it's always `(props: XProps) => JSX.Element`).
|
|
164
164
|
|
|
165
165
|
**Step 3 — Link Props to Components:**
|
|
166
166
|
|
|
@@ -185,7 +185,7 @@ Extract non-Props type exports using standard AST patterns (same as Forge tier):
|
|
|
185
185
|
|
|
186
186
|
When multiple design system variants exist:
|
|
187
187
|
|
|
188
|
-
1. **Group components by registry `id`** (
|
|
188
|
+
1. **Group components by registry `id`** (not by filename — registry is source of truth):
|
|
189
189
|
- For each `id` in `component_catalog[]`, collect all variant paths from `available_in[]` and `code_paths[]`
|
|
190
190
|
|
|
191
191
|
2. **Select canonical props definition:**
|
|
@@ -243,33 +243,6 @@ Display: "**Component extraction complete.** Returning to main extraction flow."
|
|
|
243
243
|
|
|
244
244
|
## RETURN PROTOCOL
|
|
245
245
|
|
|
246
|
-
After Phase 6 completes, return control to step 3 section 5 (Build Extraction Inventory). The extraction results from this step are merged into the standard extraction inventory format. Step-03 continues with its normal Gate 2 summary and
|
|
246
|
+
After Phase 6 completes, return control to step 3 section 5 (Build Extraction Inventory). The extraction results from this step are merged into the standard extraction inventory format. Step-03 continues with its normal Gate 2 summary and confirmation.
|
|
247
247
|
|
|
248
|
-
Do
|
|
249
|
-
|
|
250
|
-
---
|
|
251
|
-
|
|
252
|
-
## SYSTEM SUCCESS/FAILURE METRICS
|
|
253
|
-
|
|
254
|
-
### SUCCESS:
|
|
255
|
-
|
|
256
|
-
- Demo/example files detected and excluded with user confirmation
|
|
257
|
-
- Registry detected (or user provided path) and parsed into component_catalog
|
|
258
|
-
- Props interfaces extracted as primary API contracts
|
|
259
|
-
- Components linked to Props via 3-level fallback chain
|
|
260
|
-
- Variant consolidation produced deduplicated counts (if applicable)
|
|
261
|
-
- All extracted items have provenance citations
|
|
262
|
-
- Results compatible with step 3 section 5 inventory format
|
|
263
|
-
- component_catalog stored in context for step 5
|
|
264
|
-
|
|
265
|
-
### FAILURE:
|
|
266
|
-
|
|
267
|
-
- Excluding demo files without user confirmation
|
|
268
|
-
- Accepting a registry candidate without user confirmation
|
|
269
|
-
- Not extracting Props interfaces as primary API surface
|
|
270
|
-
- Documenting component function signatures instead of Props
|
|
271
|
-
- Including hallucinated component data not in source
|
|
272
|
-
- Variant deduplication based on filenames instead of registry IDs
|
|
273
|
-
- Not returning control to step 3 after completion
|
|
274
|
-
|
|
275
|
-
**Master Rule:** Zero hallucination — every extraction must trace to source code. The component registry is the source of truth for the API surface.
|
|
248
|
+
Do not load `{returnToStep}` — the calling step (step 3) continues from where it delegated.
|
|
@@ -29,7 +29,7 @@ Query the ecosystem using the skill name from the brief:
|
|
|
29
29
|
- Enforce 5-second timeout — if the query does not return within 5 seconds, treat as no match. Rationale: ecosystem check is an opportunistic advisory; a slow or degraded registry must not stall the compilation pipeline, and 5s is well beyond any healthy registry's p99 latency.
|
|
30
30
|
- Cache results for 24 hours (if re-running same skill). Rationale: the agentskills.io registry publishes new official skills in daily batches; a 24-hour TTL balances freshness against redundant network calls during iterative brief refinement.
|
|
31
31
|
|
|
32
|
-
**If registry API is
|
|
32
|
+
**If registry API is not available (current default):**
|
|
33
33
|
|
|
34
34
|
Skip completely and silently. Do not output any message about API unavailability or the ecosystem check being skipped. Emit zero text to the console. Proceed exactly as if no match was found.
|
|
35
35
|
|
|
@@ -59,32 +59,16 @@ Auto-proceed silently to next step. Do not display any message about the ecosyst
|
|
|
59
59
|
|
|
60
60
|
Auto-proceed silently. Log a note in context: "Ecosystem check skipped (timeout/error) — proceeding with compilation."
|
|
61
61
|
|
|
62
|
-
### 3.
|
|
62
|
+
### 3. Gate — Ecosystem Match (conditional)
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
This gate fires only when §2 found a match; on no match, timeout, or unavailable tool the step already auto-proceeded to `{nextStepFile}` with no menu.
|
|
65
65
|
|
|
66
|
-
|
|
66
|
+
**GATE [default: P]** — under `{headless_mode}` with a match, auto-proceed as [P], log "headless: ecosystem match found, auto-proceeding", and append `{step: "ecosystem-check", gate: "ecosystem-match", decision: "P", rationale: "headless mode — match found, auto-proceed with user's own compilation", timestamp: {ISO}}` to `headless_decisions[]` and, the moment it lands, append the same object as a JSON line to the durable audit sink `{sidecar_path}/auto-decisions.jsonl` (the on-landing append established at step 1 §3) — the sink feeds the evidence-report `## Auto-Decisions` table at step 5 §7 and step 6 §8.
|
|
67
67
|
|
|
68
|
-
|
|
68
|
+
Interactively, halt and wait for the user's choice on the §2 menu:
|
|
69
69
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
-
|
|
73
|
-
-
|
|
74
|
-
- This menu ONLY appears when an ecosystem match is found
|
|
75
|
-
- If no match, timeout, or tool unavailable — auto-proceed with no menu
|
|
76
|
-
|
|
77
|
-
#### Menu Handling Logic:
|
|
78
|
-
|
|
79
|
-
- IF P: Note user's decision to proceed despite existing skill. Immediately load, read entire file, then execute `{nextStepFile}`
|
|
80
|
-
- IF I: Display: "Install the existing skill using: `[SF] Setup Forge → install {matched_skill_name}`" then halt workflow. Do not proceed to extraction.
|
|
81
|
-
- IF A: Display: "Compilation aborted. Return to Ferris menu to select another action." then halt workflow.
|
|
82
|
-
- IF no match/timeout/error: Auto-proceed — immediately load, read entire file, then execute `{nextStepFile}`
|
|
83
|
-
- IF Any other comments or queries: help user respond then redisplay the menu
|
|
84
|
-
|
|
85
|
-
## CRITICAL STEP COMPLETION NOTE
|
|
86
|
-
|
|
87
|
-
ONLY WHEN the ecosystem check is complete (match evaluated, user decision made if applicable) will you proceed to load `{nextStepFile}` for source extraction.
|
|
88
|
-
|
|
89
|
-
If no match is found, this step auto-proceeds with no user interaction.
|
|
70
|
+
- **P** — proceed despite the existing skill; load `{nextStepFile}`, read it fully, then execute it.
|
|
71
|
+
- **I** — display "Install the existing skill using: `[SF] Setup Forge → install {matched_skill_name}`", then halt (no extraction).
|
|
72
|
+
- **A** — display "Compilation aborted. Return to Ferris menu to select another action.", then halt.
|
|
73
|
+
- Any other question — answer it, then redisplay the menu.
|
|
90
74
|
|