bmad-module-skill-forge 0.7.2 → 0.7.3
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/package.json +1 -1
- package/src/knowledge/qmd-registry.md +1 -1
- package/src/workflows/analyze-source/data/skill-brief-schema.md +3 -1
- package/src/workflows/analyze-source/steps-c/step-05-recommend.md +4 -4
- package/src/workflows/brief-skill/data/skill-brief-schema.md +3 -1
- package/src/workflows/brief-skill/steps-c/step-02-analyze-target.md +8 -0
- package/src/workflows/brief-skill/steps-c/step-03-scope-definition.md +6 -6
- package/src/workflows/brief-skill/steps-c/step-04-confirm-brief.md +4 -4
- package/src/workflows/create-skill/data/compile-assembly-rules.md +1 -0
- package/src/workflows/create-skill/data/extraction-patterns.md +45 -2
- package/src/workflows/create-skill/data/skill-sections.md +2 -1
- package/src/workflows/create-skill/steps-c/step-02b-ccc-discover.md +3 -1
- package/src/workflows/create-skill/steps-c/step-03b-fetch-temporal.md +2 -2
- package/src/workflows/create-skill/steps-c/step-03c-fetch-docs.md +2 -2
- package/src/workflows/create-skill/steps-c/step-05-compile.md +13 -2
- package/src/workflows/create-skill/steps-c/step-06-validate.md +10 -6
- package/src/workflows/test-skill/data/source-access-protocol.md +8 -2
- package/src/workflows/test-skill/steps-c/step-03-coverage-check.md +2 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "bmad-module-skill-forge",
|
|
4
|
-
"version": "0.7.
|
|
4
|
+
"version": "0.7.3",
|
|
5
5
|
"description": "BMAD module — Turn code and docs into instructions AI agents can actually follow. Progressive capability tiers (Quick/Forge/Forge+/Deep).",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"bmad",
|
|
@@ -127,7 +127,7 @@ These registries are orthogonal — they never reference each other, and their j
|
|
|
127
127
|
|
|
128
128
|
```
|
|
129
129
|
qmd collection remove {name}-extraction (if exists)
|
|
130
|
-
qmd collection add skills/{name} --name {name}-extraction --mask "**/*"
|
|
130
|
+
qmd collection add {project-root}/skills/{name} --name {name}-extraction --mask "**/*"
|
|
131
131
|
qmd embed
|
|
132
132
|
```
|
|
133
133
|
|
|
@@ -9,7 +9,7 @@ Defines the output contract for skill-brief.yaml files generated by analyze-sour
|
|
|
9
9
|
| Field | Type | Constraint | Description |
|
|
10
10
|
|-------|------|------------|-------------|
|
|
11
11
|
| name | string | kebab-case `[a-z0-9-]+` | Unique skill identifier |
|
|
12
|
-
| version | string | Semantic `X.Y.Z` | Auto-detect from source (see Version Detection below), fall back to `1.0.0` |
|
|
12
|
+
| version | string | Semantic version (`X.Y.Z` or `X.Y.Z-prerelease`) | Auto-detect from source (see Version Detection below), fall back to `1.0.0` |
|
|
13
13
|
| source_repo | string | GitHub URL or local path | Repository or project root (optional when `source_type: "docs-only"`) |
|
|
14
14
|
| language | string | Recognized language | Primary programming language |
|
|
15
15
|
| scope | object | See Scope Object below | Boundary definition |
|
|
@@ -49,6 +49,8 @@ If detection succeeds, use the detected version. If it fails or returns a non-se
|
|
|
49
49
|
|
|
50
50
|
The create-skill workflow (step-03-extract) also performs version reconciliation at extraction time — if the source version has changed since the brief was created, the extraction step warns and uses the source version.
|
|
51
51
|
|
|
52
|
+
**Pre-release handling:** If the detected version contains a pre-release tag (e.g., `1.0.0-beta.0`, `2.0.0-rc.1`), preserve it as-is. Pre-release tags are valid semver and must not be stripped. When comparing versions during reconciliation, use semver-aware comparison that respects pre-release ordering.
|
|
53
|
+
|
|
52
54
|
## Scope Object
|
|
53
55
|
|
|
54
56
|
```yaml
|
|
@@ -5,8 +5,8 @@ description: 'Present unit recommendations with rationale for user confirmation
|
|
|
5
5
|
nextStepFile: './step-06-generate-briefs.md'
|
|
6
6
|
outputFile: '{forge_data_folder}/analyze-source-report-{project_name}.md'
|
|
7
7
|
schemaFile: '../data/skill-brief-schema.md'
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
advancedElicitationSkill: '/bmad-advanced-elicitation'
|
|
9
|
+
partyModeSkill: '/bmad-party-mode'
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
# Step 5: Recommend
|
|
@@ -193,8 +193,8 @@ Display: "**Select an Option:** [A] Advanced Elicitation [P] Party Mode [D] Disc
|
|
|
193
193
|
|
|
194
194
|
#### Menu Handling Logic:
|
|
195
195
|
|
|
196
|
-
- IF A:
|
|
197
|
-
- IF P:
|
|
196
|
+
- IF A: Invoke {advancedElicitationSkill}, and when finished redisplay the menu
|
|
197
|
+
- IF P: Invoke {partyModeSkill}, and when finished redisplay the menu
|
|
198
198
|
- IF D: Accept a new repo path/URL from the user. Run a lightweight scan + classify (subset of steps 02-03) for the new source only. Merge new units into the existing report and update `project_paths[]` in frontmatter. Run export mapping for the new units (same logic as step 04 section 2). Generate recommendation cards for the new units and present them for confirmation. Then redisplay this menu.
|
|
199
199
|
- IF C: Save recommendations to {outputFile}, update frontmatter, then load, read entire file, then execute {nextStepFile}
|
|
200
200
|
- IF Any other comments or queries: help user respond then [Redisplay Menu Options](#8-present-menu-options)
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
| Field | Type | Constraint | Description |
|
|
6
6
|
|-------|------|------------|-------------|
|
|
7
7
|
| name | string | kebab-case `[a-z0-9-]+` | Unique skill identifier |
|
|
8
|
-
| version | string | Semantic `X.Y.Z` | Auto-detect from source (see Version Detection below), fall back to `1.0.0` |
|
|
8
|
+
| version | string | Semantic version (`X.Y.Z` or `X.Y.Z-prerelease`) | Auto-detect from source (see Version Detection below), fall back to `1.0.0` |
|
|
9
9
|
| source_repo | string | GitHub URL or local path | Repository or project root (optional when `source_type: "docs-only"`) |
|
|
10
10
|
| language | string | Recognized language | Primary programming language |
|
|
11
11
|
| scope | object | See Scope Object below | Boundary definition |
|
|
@@ -45,6 +45,8 @@ If detection succeeds, use the detected version. If it fails or returns a non-se
|
|
|
45
45
|
|
|
46
46
|
The create-skill workflow (step-03-extract) also performs version reconciliation at extraction time — if the source version has changed since the brief was created, the extraction step warns and uses the source version.
|
|
47
47
|
|
|
48
|
+
**Pre-release handling:** If the detected version contains a pre-release tag (e.g., `1.0.0-beta.0`, `2.0.0-rc.1`), preserve it as-is. Pre-release tags are valid semver and must not be stripped. When comparing versions during reconciliation, use semver-aware comparison that respects pre-release ordering.
|
|
49
|
+
|
|
48
50
|
## Scope Object Structure
|
|
49
51
|
|
|
50
52
|
```yaml
|
|
@@ -60,6 +60,12 @@ To analyze the target repository by resolving its location, reading its structur
|
|
|
60
60
|
**For GitHub URLs:**
|
|
61
61
|
- Use `gh api repos/{owner}/{repo}` to verify the repository exists
|
|
62
62
|
- Use `gh api repos/{owner}/{repo}/git/trees/HEAD?recursive=1` to get the file tree
|
|
63
|
+
|
|
64
|
+
**Truncation detection:** After receiving the tree response, check the `truncated` field in the JSON output. If `truncated: true`:
|
|
65
|
+
- Display: "Note: GitHub API returned a truncated tree response ({count} items). Full analysis may require a local clone."
|
|
66
|
+
- Record in analysis summary: "Tree listing is partial — some files may not appear in the analysis."
|
|
67
|
+
- For very large repos (>1000 files in tree response): suggest local clone for complete analysis.
|
|
68
|
+
|
|
63
69
|
- If inaccessible: **HALT** — "**Error:** Cannot access repository at {url}. Please verify the URL is correct and you have access. If private, ensure `gh auth` is configured."
|
|
64
70
|
|
|
65
71
|
**For local paths:**
|
|
@@ -133,6 +139,8 @@ Based on detected language, identify public API surface:
|
|
|
133
139
|
|
|
134
140
|
**Semantic Signals (Forge+ and Deep with ccc only):**
|
|
135
141
|
|
|
142
|
+
**Remote source guard:** If the target source was resolved via GitHub API (remote URL, not a local file path), skip this CCC subsection — CCC requires a local source index and cannot operate on remote-only sources. Note: "CCC semantic discovery skipped — target is remote. CCC will be available during create-skill if the source is cloned locally."
|
|
143
|
+
|
|
136
144
|
If `tools.ccc` is true in forge-tier.yaml, supplement the module listing with a semantic discovery pass:
|
|
137
145
|
|
|
138
146
|
**CCC Semantic Discovery:**
|
|
@@ -4,8 +4,8 @@ description: 'Collaboratively define skill scope boundaries using analysis findi
|
|
|
4
4
|
|
|
5
5
|
nextStepFile: './step-04-confirm-brief.md'
|
|
6
6
|
scopeTemplatesFile: '../data/scope-templates.md'
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
advancedElicitationSkill: '/bmad-advanced-elicitation'
|
|
8
|
+
partyModeSkill: '/bmad-party-mode'
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
# Step 3: Scope Definition
|
|
@@ -90,7 +90,7 @@ Wait for confirmation. Then skip to section 5 (Summarize Scope Decisions) with:
|
|
|
90
90
|
|
|
91
91
|
**If `source_type: "source"` (default):** Continue to scope templates below.
|
|
92
92
|
|
|
93
|
-
###
|
|
93
|
+
### 2b. Confirm Supplemental Documentation (if doc_urls collected)
|
|
94
94
|
|
|
95
95
|
**If `source_type: "source"` AND supplemental `doc_urls` were collected in step 01:**
|
|
96
96
|
|
|
@@ -104,7 +104,7 @@ Wait for confirmation. Record any changes to `doc_urls`.
|
|
|
104
104
|
|
|
105
105
|
**If no supplemental doc_urls were collected:** Skip this subsection.
|
|
106
106
|
|
|
107
|
-
###
|
|
107
|
+
### 2c. Offer Scope Templates
|
|
108
108
|
|
|
109
109
|
Load `{scopeTemplatesFile}` for the scope type options ([F], [M], [P]) and their descriptions.
|
|
110
110
|
|
|
@@ -167,8 +167,8 @@ Display: **Select an Option:** [A] Advanced Elicitation [P] Party Mode [C] Conti
|
|
|
167
167
|
|
|
168
168
|
#### Menu Handling Logic:
|
|
169
169
|
|
|
170
|
-
- IF A:
|
|
171
|
-
- IF P:
|
|
170
|
+
- IF A: Invoke {advancedElicitationSkill}, and when finished redisplay the menu
|
|
171
|
+
- IF P: Invoke {partyModeSkill}, and when finished redisplay the menu
|
|
172
172
|
- IF C: Load, read entire file, then execute {nextStepFile}
|
|
173
173
|
- IF Any other comments or queries: help user respond then [Redisplay Menu Options](#6-present-menu-options)
|
|
174
174
|
|
|
@@ -5,8 +5,8 @@ description: 'Present complete skill brief for user review and confirmation befo
|
|
|
5
5
|
nextStepFile: './step-05-write-brief.md'
|
|
6
6
|
reviseStepFile: './step-03-scope-definition.md'
|
|
7
7
|
briefSchemaFile: '../data/skill-brief-schema.md'
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
advancedElicitationSkill: '/bmad-advanced-elicitation'
|
|
9
|
+
partyModeSkill: '/bmad-party-mode'
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
# Step 4: Confirm Brief
|
|
@@ -165,8 +165,8 @@ Display: **Select an Option:** [R] Revise Scope [A] Advanced Elicitation [P] Par
|
|
|
165
165
|
#### Menu Handling Logic:
|
|
166
166
|
|
|
167
167
|
- IF R: Load, read entire file, then execute {reviseStepFile} to re-enter scope definition
|
|
168
|
-
- IF A:
|
|
169
|
-
- IF P:
|
|
168
|
+
- IF A: Invoke {advancedElicitationSkill}, and when finished redisplay the menu
|
|
169
|
+
- IF P: Invoke {partyModeSkill}, and when finished redisplay the menu
|
|
170
170
|
- IF C: Load, read entire file, then execute {nextStepFile}
|
|
171
171
|
- IF Any other comments or queries: help user respond, apply any field adjustments, re-present brief if changed, then [Redisplay Menu Options](#6-present-menu-options)
|
|
172
172
|
|
|
@@ -116,6 +116,7 @@ Do NOT repeat Tier 1's name/purpose/key-params table format in Tier 2. Tier 2 is
|
|
|
116
116
|
4. If Tier 1 alone exceeds 300 lines, reduce Key API Summary and Architecture at a Glance
|
|
117
117
|
5. Tier 1 sections are kept short enough that `split-body` targets the larger Tier 2 sections (`## Full ...` headings) instead
|
|
118
118
|
6. After split-body, SKILL.md must still contain all Tier 1 sections with actionable content
|
|
119
|
+
7. **Signature fidelity:** When populating function entries from the extraction inventory, always use the `params` and `return_type` fields from the provenance-map entry (T1/AST-backed). Do not substitute parameter names, types, or return types from documentation, README examples, or enrichment annotations. T2/T3 sources may enrich descriptions and add usage notes, but structural signature data from AST extraction is authoritative.
|
|
119
120
|
|
|
120
121
|
### Reference File Rules
|
|
121
122
|
|
|
@@ -51,7 +51,7 @@ Structural extraction via ast-grep — verified exports with line-level citation
|
|
|
51
51
|
- Internal/private functions: excluded (not part of public API)
|
|
52
52
|
|
|
53
53
|
### ast-grep Patterns
|
|
54
|
-
- JS/TS: `export function $NAME($$$PARAMS): $RET` / `export const $NAME`
|
|
54
|
+
- JS/TS: `export function $NAME($$$PARAMS): $RET` / `export const $NAME = ($$$PARAMS) => $BODY` / `export const $NAME` / `export class $NAME`
|
|
55
55
|
- Rust: `pub fn $NAME($$$PARAMS) -> $RET`
|
|
56
56
|
- Python: function definitions within `__all__` list
|
|
57
57
|
- Go: capitalized function definitions
|
|
@@ -260,6 +260,32 @@ rule:
|
|
|
260
260
|
pattern: 'export const $NAME = $VALUE'
|
|
261
261
|
```
|
|
262
262
|
|
|
263
|
+
**JavaScript/TypeScript — exported arrow functions:**
|
|
264
|
+
|
|
265
|
+
```yaml
|
|
266
|
+
id: js-exported-arrow-functions
|
|
267
|
+
language: typescript
|
|
268
|
+
rule:
|
|
269
|
+
pattern: 'export const $NAME = ($$$PARAMS) => $BODY'
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
> **JS/TS Pattern Merging:** Modern TypeScript codebases often use `export const` exclusively for all exports (arrow functions, objects, constants). Run ALL four JS/TS patterns (functions, arrow functions, constants, classes) and merge results by `$NAME`. Priority when deduplicating: arrow function match > function declaration match > constant match. Arrow function matches capture parameters directly; constant matches require inspecting `$VALUE` to extract signatures.
|
|
273
|
+
|
|
274
|
+
**JavaScript/TypeScript — exported classes (use `find_code`, not `find_code_by_rule`):**
|
|
275
|
+
|
|
276
|
+
```yaml
|
|
277
|
+
id: js-exported-classes
|
|
278
|
+
language: typescript
|
|
279
|
+
rule:
|
|
280
|
+
pattern: 'export class $NAME'
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
> **Important:** For class patterns, use `find_code()` rather than `find_code_by_rule()`. The `find_code_by_rule` API requires explicit AST `kind` rules for class exports, which adds complexity. The simpler `find_code()` pattern approach works reliably for class detection.
|
|
284
|
+
|
|
285
|
+
**JavaScript/TypeScript — re-export detection (use `find_code`):**
|
|
286
|
+
|
|
287
|
+
Use `find_code()` with pattern `export { $$$NAMES } from $SOURCE` for re-export detection. Note: this pattern may produce multiple AST node matches. Post-process results to split comma-separated names from `$$$NAMES`. For complex re-export chains (aliased exports, default re-exports, namespace re-exports), fall back to the Re-Export Tracing protocol in `extraction-patterns-tracing.md`.
|
|
288
|
+
|
|
263
289
|
**Rust — public functions:**
|
|
264
290
|
|
|
265
291
|
```yaml
|
|
@@ -277,12 +303,29 @@ rule:
|
|
|
277
303
|
id: go-exported-functions
|
|
278
304
|
language: go
|
|
279
305
|
rule:
|
|
280
|
-
|
|
306
|
+
any:
|
|
307
|
+
- pattern: 'func $NAME($$$PARAMS) $RET'
|
|
308
|
+
- pattern: 'func $NAME($$$PARAMS)'
|
|
281
309
|
constraints:
|
|
282
310
|
NAME:
|
|
283
311
|
regex: '^[A-Z]'
|
|
284
312
|
```
|
|
285
313
|
|
|
314
|
+
### Known ast-grep Limitations
|
|
315
|
+
|
|
316
|
+
When using ast-grep for extraction, be aware of these documented limitations:
|
|
317
|
+
|
|
318
|
+
1. **`find_code_by_rule` requires explicit `kind` for class exports:** The `export class $NAME` pattern needs a `kind` rule specifying the tree-sitter node type when used with `find_code_by_rule`. Use the simpler `find_code()` API instead for class detection.
|
|
319
|
+
|
|
320
|
+
2. **Re-export patterns produce multiple AST nodes:** `export { A, B, C } from './module'` decomposes into multiple metavariable bindings for `$$$NAMES`. Results require post-processing to split comma-separated names.
|
|
321
|
+
|
|
322
|
+
3. **Default anonymous exports capture no name:** `export default function $NAME` works, but `export default $EXPR` (anonymous default export) captures no name in `$NAME`. Fall back to source reading (T1-low) for anonymous defaults.
|
|
323
|
+
|
|
324
|
+
4. **Fallback protocol:** If an ast-grep pattern returns errors or zero results when results are expected:
|
|
325
|
+
- First: retry with `find_code()` using a simpler pattern (drop type annotations, use broader match)
|
|
326
|
+
- Second: if `find_code()` also fails, fall back to source reading for that pattern category (T1-low confidence)
|
|
327
|
+
- Never silently accept zero results for a pattern category that the source language commonly uses
|
|
328
|
+
|
|
286
329
|
### Re-Export Tracing and Script/Asset Extraction
|
|
287
330
|
|
|
288
331
|
See `extraction-patterns-tracing.md` for:
|
|
@@ -199,7 +199,8 @@ Each reference file includes:
|
|
|
199
199
|
"source_line": 42,
|
|
200
200
|
"confidence": "T1",
|
|
201
201
|
"extraction_method": "ast-grep",
|
|
202
|
-
"ast_node_type": "export_function_declaration"
|
|
202
|
+
"ast_node_type": "export_function_declaration",
|
|
203
|
+
"signature_source": "T1"
|
|
203
204
|
}
|
|
204
205
|
],
|
|
205
206
|
"file_entries": [
|
|
@@ -47,7 +47,7 @@ For Quick and Forge tiers, or when ccc is unavailable, skip silently and proceed
|
|
|
47
47
|
|
|
48
48
|
- Available: tier, tools.ccc, ccc_index from forge-tier.yaml (loaded in step-01)
|
|
49
49
|
- Available: brief_data (name, scope, description) from step-01
|
|
50
|
-
- Available: source_root (resolved source path) from step-01
|
|
50
|
+
- Available: source_root (resolved source path) from step-01 — note: for remote sources, `source_root` may not be a local path until step-03 performs the ephemeral clone
|
|
51
51
|
- Focus: Semantic discovery only — no extraction, no compilation
|
|
52
52
|
- Dependencies: step-02 must have completed
|
|
53
53
|
|
|
@@ -67,6 +67,8 @@ Check `tools.ccc` from forge-tier.yaml. If `tools.ccc` is false, set `{ccc_disco
|
|
|
67
67
|
|
|
68
68
|
If `tools.ccc` is true, continue to section 2.
|
|
69
69
|
|
|
70
|
+
**Remote source guard:** If `source_root` is a remote URL (GitHub repository not yet cloned locally — ephemeral clone happens in step-03), CCC cannot operate. Set `{ccc_discovery: []}` and display: "CCC discovery skipped — remote source not yet available locally. CCC requires a local source index." Auto-proceed to the step completion / next step section.
|
|
71
|
+
|
|
70
72
|
### 2. Check CCC Index State
|
|
71
73
|
|
|
72
74
|
Read `ccc_index` from forge-tier.yaml:
|
|
@@ -172,7 +172,7 @@ If a `{skill-name}-temporal` collection already exists, remove and recreate for
|
|
|
172
172
|
|
|
173
173
|
```bash
|
|
174
174
|
qmd collection remove {skill-name}-temporal
|
|
175
|
-
qmd collection add _bmad-output/{skill-name}-temporal/ --name {skill-name}-temporal --mask "*.md"
|
|
175
|
+
qmd collection add {project-root}/_bmad-output/{skill-name}-temporal/ --name {skill-name}-temporal --mask "*.md"
|
|
176
176
|
qmd embed
|
|
177
177
|
```
|
|
178
178
|
|
|
@@ -193,7 +193,7 @@ If an entry with `name: "{skill-name}-temporal"` already exists in `qmd_collecti
|
|
|
193
193
|
**Clean up** the staging directory after successful indexing:
|
|
194
194
|
|
|
195
195
|
```bash
|
|
196
|
-
rm -rf _bmad-output/{skill-name}-temporal/
|
|
196
|
+
rm -rf {project-root}/_bmad-output/{skill-name}-temporal/
|
|
197
197
|
```
|
|
198
198
|
|
|
199
199
|
**Error handling:**
|
|
@@ -153,7 +153,7 @@ Parse the successfully fetched markdown for:
|
|
|
153
153
|
**If tier is Deep and at least one URL was fetched successfully:**
|
|
154
154
|
|
|
155
155
|
1. Write fetched markdown files to a staging directory: `_bmad-output/{skill-name}-docs/`
|
|
156
|
-
2. Index into QMD: `qmd collection add _bmad-output/{skill-name}-docs/ --name {skill-name}-docs --mask "*.md"`
|
|
156
|
+
2. Index into QMD: `qmd collection add {project-root}/_bmad-output/{skill-name}-docs/ --name {skill-name}-docs --mask "*.md"`
|
|
157
157
|
3. Generate embeddings: `qmd embed` (required for `vector_search` and `deep_search`)
|
|
158
158
|
4. Register in forge-tier.yaml `qmd_collections` array:
|
|
159
159
|
|
|
@@ -165,7 +165,7 @@ Parse the successfully fetched markdown for:
|
|
|
165
165
|
created_at: "{current ISO date}"
|
|
166
166
|
```
|
|
167
167
|
|
|
168
|
-
5. Clean up staging directory after indexing: `rm -rf _bmad-output/{skill-name}-docs/`
|
|
168
|
+
5. Clean up staging directory after indexing: `rm -rf {project-root}/_bmad-output/{skill-name}-docs/`
|
|
169
169
|
|
|
170
170
|
**If QMD indexing fails:** Warn: "QMD indexing of fetched docs failed. T3 items are still in the extraction inventory — enrichment will proceed without QMD-indexed docs." Continue.
|
|
171
171
|
|
|
@@ -59,6 +59,17 @@ To assemble the complete skill content from the extraction inventory and enrichm
|
|
|
59
59
|
|
|
60
60
|
Load `{skillSectionsData}` and `{assemblyRulesData}` completely. These define the agentskills.io-compliant format and detailed assembly rules for all output artifacts.
|
|
61
61
|
|
|
62
|
+
### 1b. Signature Fidelity Rule
|
|
63
|
+
|
|
64
|
+
**When assembling function signatures, parameter lists, and return types in any SKILL.md section or reference file:**
|
|
65
|
+
|
|
66
|
+
- **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`).
|
|
67
|
+
- **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.
|
|
68
|
+
- **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."
|
|
69
|
+
- **`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.
|
|
70
|
+
|
|
71
|
+
This rule applies to ALL sections including Tier 1 Key API Summary, Tier 2 Full API Reference, and Section 4b Migration & Deprecation Warnings.
|
|
72
|
+
|
|
62
73
|
### 2. Build SKILL.md Content
|
|
63
74
|
|
|
64
75
|
Assemble each section in order using the assembly rules data file (`{assemblyRulesData}`). The data file specifies frontmatter format, Tier 1 section details (Sections 1-8, including conditional Section 7b for scripts/assets), Tier 2 section details (Sections 9-11), and assembly ordering rules. Follow it exactly. Assemble Section 7b (Scripts & Assets) only if `scripts_inventory` or `assets_inventory` is non-empty.
|
|
@@ -92,7 +103,7 @@ Following the structure from the skill-sections data file:
|
|
|
92
103
|
- Set `source_commit` from resolved source (if available)
|
|
93
104
|
- Set `stats` from extraction aggregate counts:
|
|
94
105
|
- `exports_documented`: count of exports with documentation in the assembled SKILL.md
|
|
95
|
-
- `exports_public_api`: count of exports from public entry points (`__init__.py`, `index.ts`, `lib.rs`, or equivalent)
|
|
106
|
+
- `exports_public_api`: count of exports from public entry points (`__init__.py`, `index.ts`, `lib.rs`, or equivalent) — derive this from step-03's entry-point validation (section 4b), NOT from the provenance-map entry count (which may be incomplete if extraction patterns missed some export types)
|
|
96
107
|
- `exports_internal`: count of all other non-underscore-prefixed exports (internal modules, helpers, adapters)
|
|
97
108
|
- `exports_total`: `exports_public_api` + `exports_internal`
|
|
98
109
|
- `public_api_coverage`: `exports_documented / exports_public_api` (1.0 when all public API exports are documented; `null` if `exports_public_api` is 0)
|
|
@@ -121,7 +132,7 @@ Group functions logically by module, file, or functional area.
|
|
|
121
132
|
|
|
122
133
|
### 6. Build provenance-map.json Content
|
|
123
134
|
|
|
124
|
-
One entry per extracted export: export_name, export_type, params[] (typed strings), return_type, source_file, source_line, confidence tier (T1/T1-low/T2), extraction_method, ast_node_type. If `scripts_inventory` or `assets_inventory` is non-empty, add `file_entries[]` with file_name, file_type, source_file, content_hash, confidence, extraction_method. See `{skillSectionsData}` for full schema.
|
|
135
|
+
One entry per extracted export: export_name, export_type, params[] (typed strings), return_type, source_file, source_line, confidence tier (T1/T1-low/T2), extraction_method, ast_node_type, signature_source ("T1"|"T1-low"|"T2"|"T3" — indicates which tier contributed the structural signature). If `scripts_inventory` or `assets_inventory` is non-empty, add `file_entries[]` with file_name, file_type, source_file, content_hash, confidence, extraction_method. See `{skillSectionsData}` for full schema.
|
|
125
136
|
|
|
126
137
|
### 7. Build evidence-report.md Content
|
|
127
138
|
|
|
@@ -76,6 +76,8 @@ This performs frontmatter validation, description quality checks, body limit enf
|
|
|
76
76
|
|
|
77
77
|
**Context sync after --fix:** If `fixed[]` is non-empty (i.e., `--fix` modified files on disk), re-read the modified SKILL.md to update the in-context copy. Verify the re-read content matches expectations before proceeding. This prevents silent divergence between the in-context SKILL.md and the on-disk version that step-07 will use for artifact generation.
|
|
78
78
|
|
|
79
|
+
**Description preservation after --fix:** After re-reading the modified SKILL.md, compare the frontmatter `description` field against the original step-05 compiled description. If `--fix` replaced the description with a generic or truncated version, restore the original description to the on-disk file and update the in-context copy. The step-05 compiled description is authoritative — auto-fix tools must not replace trigger-optimized descriptions.
|
|
80
|
+
|
|
79
81
|
**Note:** `skill-check` may return non-zero exit code even when `errorCount` is 0. Always rely on parsed JSON, not the shell exit code.
|
|
80
82
|
|
|
81
83
|
- **Score ≥ 70:** Record "Schema: PASS (score: {score}/100)" in evidence-report
|
|
@@ -101,15 +103,17 @@ If fails: auto-fix (deterministic), re-validate once, record result. If passes:
|
|
|
101
103
|
|
|
102
104
|
**If step 2 reported `body.max_lines` failure:**
|
|
103
105
|
|
|
104
|
-
**
|
|
106
|
+
**Description preservation:** Before any split operation, capture the current SKILL.md frontmatter `description` field. After the split completes, verify the `description` was not modified. If it was replaced with a generic placeholder, restore the original immediately.
|
|
105
107
|
|
|
106
|
-
**
|
|
108
|
+
**Mandatory approach — selective split:** Identify Tier 2 sections by their `## Full` heading prefix (e.g., `## Full API Reference`, `## Full Type Definitions`, `## Full Integration Patterns`). Extract ONLY those sections to `references/`, starting with the largest. Keep ALL Tier 1 content and any smaller sections inline. Inline passive context achieves 100% task accuracy vs 79% for on-demand retrieval (per Vercel research).
|
|
107
109
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
110
|
+
**FORBIDDEN:** Running `npx skill-check split-body --write` without prior selective extraction. The `split-body --write` command extracts ALL `##` sections top-to-bottom, destroying Tier 1 inline content that the two-tier design depends on. This command is a LAST RESORT only after selective split has been attempted and proven insufficient.
|
|
111
|
+
|
|
112
|
+
**If selective split alone does not bring body under the limit** (rare — typically only occurs when Tier 1 itself exceeds 300 lines): reduce Tier 1 Key API Summary and Architecture at a Glance sections to fit within limits. Do NOT fall back to automated `split-body --write` to solve a Tier 1 sizing problem.
|
|
113
|
+
|
|
114
|
+
**Tier 1 preservation check:** After ANY split operation, verify that ALL of the following sections remain inline in SKILL.md (not moved to references/): Overview, Quick Start, Common Workflows, Key API Summary, Migration & Deprecation Warnings (if present), Key Types, Architecture at a Glance, CLI (if present), Scripts & Assets (if present), Manual Sections. If any Tier 1 section was moved to references/, restore it immediately and re-split targeting only Tier 2 sections.
|
|
111
115
|
|
|
112
|
-
After any split
|
|
116
|
+
**Anchor validation and remediation:** After any split, verify that context-snippet section anchors (`#quick-start`, `#key-types`) still resolve to headings in SKILL.md. If an anchor no longer resolves (section was split out), restore that section to SKILL.md inline content — the context-snippet must always reference sections that exist in the main file.
|
|
113
117
|
|
|
114
118
|
Then re-validate: `npx skill-check check <staging-skill-dir> --format json --no-security-scan`
|
|
115
119
|
|
|
@@ -21,9 +21,15 @@ Before analysis, determine source access level. Walk through these states in ord
|
|
|
21
21
|
Check if `{source_path}` (from metadata.json `source_root`) exists on disk. If yes → full analysis at detected tier (AST + signatures). Set `analysis_confidence: full`.
|
|
22
22
|
|
|
23
23
|
**State 2 — Local absent, provenance-map exists:**
|
|
24
|
-
Check `{forge_data_folder}/{skill_name}/provenance-map.json`. If present, use it as the baseline export inventory — each entry contains structured fields: `export_name`, `export_type`, `params[]`, `return_type`, `source_file`, `source_line`, `confidence`, and `ast_node_type`. Cross-reference against SKILL.md documented exports for name-matching and param-by-param coverage. Signature verification compares SKILL.md's documented params/return types against provenance-map entries directly.
|
|
24
|
+
Check `{forge_data_folder}/{skill_name}/provenance-map.json`. If present AND contains at least 1 entry, use it as the baseline export inventory — each entry contains structured fields: `export_name`, `export_type`, `params[]`, `return_type`, `source_file`, `source_line`, `confidence`, and `ast_node_type`. Cross-reference against SKILL.md documented exports for name-matching and param-by-param coverage. Signature verification compares SKILL.md's documented params/return types against provenance-map entries directly.
|
|
25
25
|
|
|
26
|
-
**
|
|
26
|
+
**Cross-reference with metadata.json:** After loading provenance-map entries, compare the entry count against `metadata.json`'s `exports[]` array length and `stats.exports_public_api` count. If metadata reports more exports than provenance-map entries:
|
|
27
|
+
- Compute `gap = metadata.exports.length - provenance_map.entries.length`
|
|
28
|
+
- Report: "Provenance-map contains {pmap_count} entries but metadata.json lists {meta_count} exports ({gap} gap). Coverage denominator uses the union."
|
|
29
|
+
- Build the coverage denominator from the **union** of provenance-map entry names and metadata.json `exports[]` names. Exports present in metadata but absent from provenance-map are counted as "missing documentation" in the coverage calculation.
|
|
30
|
+
- If metadata.json is unavailable or has no `exports[]` array, use provenance-map count alone with a note: "Coverage denominator is provenance-map only — may undercount if extraction was incomplete." If remote reading tools are available (zread, deepwiki, gh API, or similar), supplement by reading the entry point file for live signature verification. Set `analysis_confidence: provenance-map`.
|
|
31
|
+
|
|
32
|
+
**State 2 limitations:** Signature verification at State 2 is **string comparison only**, not semantic. Provenance-map stores parameters as flat string arrays (e.g., `["data: Union[BinaryIO, list, str]"]`), so `str` vs `String` or `list` vs `List[Any]` would be treated as mismatches even when semantically equivalent. For full type-aware verification (handling type aliases, generic equivalence), State 1 (local source) with AST re-parsing is required. When the SKILL.md was compiled from the same provenance-map (typical for create-then-test flows), most strings will match. However, enrichment (step-04) and doc-fetching (step-03c) during compilation may alter parameter descriptions, add type annotations, or normalize signatures, causing mismatches even in create-then-test flows. Expect some string-level mismatches and treat them as compilation artifacts, not source drift signals, until signature fidelity is enforced by step-05's Signature Fidelity Rule (see `signature_source` field in provenance-map entries).
|
|
27
33
|
|
|
28
34
|
**State 3 — No provenance-map, metadata exports exist (quick-skill path):**
|
|
29
35
|
If no provenance-map.json exists (typical for quick-skill output), fall back to `metadata.json`'s `exports[]` array for the export name list. Coverage check becomes a self-consistency comparison: are all names in `exports[]` documented in SKILL.md with description, parameters, and return type? Signatures cannot be verified. If remote reading tools are available, supplement by reading the entry point for live export comparison. Set `analysis_confidence: metadata-only`.
|
|
@@ -185,6 +185,8 @@ Load `{scoringRulesFile}` to determine category scores:
|
|
|
185
185
|
- **Signature Accuracy:** (matching_signatures / total_documented) * 100 (Forge/Deep only, "N/A" for Quick)
|
|
186
186
|
- **Type Coverage:** (documented_types / total_types) * 100 (Forge/Deep only, "N/A" for Quick)
|
|
187
187
|
|
|
188
|
+
**State 2 denominator validation:** When using provenance-map as the baseline (State 2), cross-reference the provenance-map entry count against `metadata.json`'s `exports[]` array before computing Export Coverage. If they diverge, use the union as the denominator per the source-access-protocol rules. Log the gap size if any.
|
|
189
|
+
|
|
188
190
|
### 5. Append Coverage Analysis to Output
|
|
189
191
|
|
|
190
192
|
Append the **Coverage Analysis** section to `{outputFile}`:
|