bmad-module-skill-forge 0.7.2 → 0.7.4
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/ccc-bridge.md +32 -0
- 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 +6 -2
- package/src/workflows/create-skill/steps-c/step-03-extract.md +22 -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/setup-forge/steps-c/step-01b-ccc-index.md +65 -13
- package/src/workflows/setup-forge/steps-c/step-02-write-config.md +5 -3
- 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/src/workflows/update-skill/steps-c/step-03-re-extract.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.4",
|
|
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",
|
|
@@ -77,6 +77,36 @@ The ccc search is invisible in the output artifact. A Forge+ skill's citations a
|
|
|
77
77
|
- A stale index still produces useful results — the workflow proceeds with the stale index and notes the staleness
|
|
78
78
|
- setup-forge is the designated refresh authority
|
|
79
79
|
|
|
80
|
+
### Exclusion Patterns
|
|
81
|
+
|
|
82
|
+
CCC stores its configuration at `{project-root}/.cocoindex_code/settings.yml`. This file contains `exclude_patterns` and `include_patterns` arrays in glob format. `ccc init` creates the file with sensible defaults (excludes `node_modules`, `__pycache__`, hidden dirs, etc.).
|
|
83
|
+
|
|
84
|
+
**SKF infrastructure exclusions:** setup-forge step-01b appends SKF-specific exclusion patterns after `ccc init` creates the default config. These patterns prevent indexing of framework and output directories that have zero value for source extraction:
|
|
85
|
+
|
|
86
|
+
| Pattern | Purpose |
|
|
87
|
+
|---------|---------|
|
|
88
|
+
| `**/_bmad` | SKF framework module (workflow instructions, agents, knowledge) |
|
|
89
|
+
| `**/_bmad-output` | Build output artifacts (TODO files, reports) |
|
|
90
|
+
| `**/.claude` | Claude Code configuration |
|
|
91
|
+
| `**/_skf-learn` | SKF learning materials |
|
|
92
|
+
| `**/{skills_output_folder}` | Generated skill files (from manifest, default: `skills`) |
|
|
93
|
+
| `**/{forge_data_folder}` | Compilation workspace (from manifest, default: `forge-data`) |
|
|
94
|
+
|
|
95
|
+
The `skills_output_folder` and `forge_data_folder` values are read from `_bmad/_config/skf-manifest.yaml` when available, falling back to the defaults `skills` and `forge-data`. Patterns are appended only if not already present — user customizations to `settings.yml` are preserved.
|
|
96
|
+
|
|
97
|
+
The configured exclusion patterns are stored in `ccc_index.exclude_patterns` in forge-tier.yaml for reference.
|
|
98
|
+
|
|
99
|
+
### Deferred Discovery (Remote Sources)
|
|
100
|
+
|
|
101
|
+
For remote repository sources (GitHub URLs), CCC cannot operate during step-02b because no local code exists yet. The ephemeral clone happens in step-03. To provide CCC pre-ranking for remote sources:
|
|
102
|
+
|
|
103
|
+
1. **step-02b:** Detects remote source, sets `{ccc_discovery: []}`, displays deferred message
|
|
104
|
+
2. **step-03:** After ephemeral clone succeeds, detects the deferred scenario (`tools.ccc == true AND {ccc_discovery} is empty AND ephemeral_clone_active == true AND tier is Forge+/Deep`)
|
|
105
|
+
3. **step-03:** Runs `ccc init {temp_path}` + `ccc index` on the ephemeral clone (extended timeout or background mode, verified via `ccc status`)
|
|
106
|
+
4. **step-03:** Executes CCC search and populates `{ccc_discovery}` before AST extraction begins
|
|
107
|
+
|
|
108
|
+
The ephemeral clone index is not registered in `ccc_index_registry` — the clone is deleted after extraction and the CCC daemon's own GC handles orphaned indexes.
|
|
109
|
+
|
|
80
110
|
### Relationship to QMD Registry
|
|
81
111
|
|
|
82
112
|
ccc_index and qmd_collections are **orthogonal**:
|
|
@@ -100,6 +130,8 @@ To prevent excessive daemon calls, workflow steps cap ccc queries:
|
|
|
100
130
|
- Running ccc_bridge.ensure_index() without checking ccc_index.status first — unnecessary re-indexing
|
|
101
131
|
- Passing ccc results directly to the extraction inventory — they are candidates, not extractions
|
|
102
132
|
- Listing ccc as "unavailable" in reports for Quick/Forge tiers — ccc is a Forge+ capability, not something Quick/Forge tiers are missing
|
|
133
|
+
- Indexing without configuring SKF exclusions — framework and output directories pollute search results
|
|
134
|
+
- Skipping CCC discovery for remote sources without deferring to step-03 — remote repos deserve the same pre-ranking as local sources
|
|
103
135
|
|
|
104
136
|
## Related Fragments
|
|
105
137
|
|
|
@@ -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 discovery will run automatically during create-skill after the source is cloned."
|
|
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
|
|
|
@@ -65,7 +65,11 @@ Set `{ccc_discovery: []}` in context. Auto-proceed silently. Display no message.
|
|
|
65
65
|
|
|
66
66
|
Check `tools.ccc` from forge-tier.yaml. If `tools.ccc` is false, set `{ccc_discovery: []}` in context and auto-proceed to section 5.
|
|
67
67
|
|
|
68
|
-
If `tools.ccc` is true,
|
|
68
|
+
If `tools.ccc` is true, check the remote source guard **before** proceeding to section 2:
|
|
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 yet. Set `{ccc_discovery: []}` and display: "CCC discovery deferred — remote source will be indexed after ephemeral clone in step-03." Auto-proceed to section 5 (step completion). Step-03 will detect the deferred scenario and run CCC discovery on the ephemeral clone before AST extraction begins.
|
|
71
|
+
|
|
72
|
+
If `source_root` is a local path, continue to section 2.
|
|
69
73
|
|
|
70
74
|
### 2. Check CCC Index State
|
|
71
75
|
|
|
@@ -96,9 +96,30 @@ Load `{sourceResolutionData}` completely. Follow the **Remote Source Resolution*
|
|
|
96
96
|
|
|
97
97
|
**Forge/Forge+/Deep Tier (AST available):**
|
|
98
98
|
|
|
99
|
+
**Deferred CCC Discovery (Forge+ and Deep — remote sources only):**
|
|
100
|
+
|
|
101
|
+
If ALL of these conditions are true:
|
|
102
|
+
- `tools.ccc` is true in forge-tier.yaml
|
|
103
|
+
- `{ccc_discovery}` is empty (step-02b deferred because source was remote)
|
|
104
|
+
- `ephemeral_clone_active` is true (clone succeeded in source resolution above)
|
|
105
|
+
- Tier is Forge+ or Deep
|
|
106
|
+
|
|
107
|
+
Then run CCC indexing and discovery on the ephemeral clone:
|
|
108
|
+
|
|
109
|
+
1. **Index the clone:** Run `ccc init {temp_path}` then `ccc index` with an extended timeout or in background mode — indexing can take several minutes on large codebases (1000+ files). Use `ccc status` to verify completion — check that `Chunks` and `Files` counts are non-zero. If init fails or indexing fails, set `{ccc_discovery: []}` and continue — this is not an error.
|
|
110
|
+
|
|
111
|
+
2. **Construct semantic query:** Build from brief data: `"{brief.name} {brief.scope}"`. Truncate to 80 characters — keep the full skill name and trim `brief.scope` from the end. If `brief.scope` is very short (< 10 chars), append terms from `brief.description` to fill the remaining space.
|
|
112
|
+
|
|
113
|
+
3. **Execute search:** Run `ccc_bridge.search(query, temp_path, top_k=20)`:
|
|
114
|
+
- **Tool resolution:** Use `/ccc` skill search (Claude Code), ccc MCP server (Cursor), or `ccc search "{query}" --path {temp_path} --top 20` (CLI). See [knowledge/tool-resolution.md](../../../knowledge/tool-resolution.md).
|
|
115
|
+
|
|
116
|
+
4. **Store results:** If search succeeds, store as `{ccc_discovery: [{file, score, snippet}]}`. Display: "**CCC semantic discovery (post-clone): {N} relevant regions identified across {M} unique files.**"
|
|
117
|
+
|
|
118
|
+
5. **On failure:** Set `{ccc_discovery: []}`. Display: "CCC post-clone discovery unavailable — proceeding with standard extraction." Do NOT halt.
|
|
119
|
+
|
|
99
120
|
**CCC Discovery Integration (Forge+ and Deep with ccc only):**
|
|
100
121
|
|
|
101
|
-
If `{ccc_discovery}` is in context and non-empty (populated by step-02b):
|
|
122
|
+
If `{ccc_discovery}` is in context and non-empty (populated by step-02b or deferred discovery above):
|
|
102
123
|
- Sort the filtered file list by CCC relevance score: files appearing in `{ccc_discovery}` results move to the front of the extraction queue, sorted by their relevance score descending
|
|
103
124
|
- Files NOT in CCC results remain in the queue after ranked files — they are not excluded, only deprioritized
|
|
104
125
|
- Display: "**CCC discovery: {N} files pre-ranked by semantic relevance** — extraction will prioritize these first."
|
|
@@ -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
|
|
|
@@ -9,7 +9,7 @@ nextStepFile: './step-02-write-config.md'
|
|
|
9
9
|
|
|
10
10
|
## STEP GOAL:
|
|
11
11
|
|
|
12
|
-
If ccc is available (`{ccc: true}` from step-01), verify that the ccc index exists for the project root
|
|
12
|
+
If ccc is available (`{ccc: true}` from step-01), configure CCC exclusion patterns for SKF infrastructure directories, verify that the ccc index exists for the project root, and create or refresh it if needed. Store index state and exclusion patterns in context for step-02 to write into forge-tier.yaml.
|
|
13
13
|
|
|
14
14
|
For Quick and Forge tiers, or when ccc is unavailable, skip silently and proceed.
|
|
15
15
|
|
|
@@ -32,7 +32,7 @@ For Quick and Forge tiers, or when ccc is unavailable, skip silently and proceed
|
|
|
32
32
|
- 🎯 Focus only on ccc index verification and creation
|
|
33
33
|
- 🚫 FORBIDDEN to display skip messages for Quick/Forge tiers
|
|
34
34
|
- 🚫 FORBIDDEN to fail the workflow if ccc indexing fails
|
|
35
|
-
- 🚫 FORBIDDEN to re-index if ccc index already exists and is fresh (< staleness threshold)
|
|
35
|
+
- 🚫 FORBIDDEN to re-index if ccc index already exists and is fresh (< staleness threshold) UNLESS new exclusion patterns were applied to settings.yml
|
|
36
36
|
|
|
37
37
|
## EXECUTION PROTOCOLS:
|
|
38
38
|
|
|
@@ -56,7 +56,7 @@ For Quick and Forge tiers, or when ccc is unavailable, skip silently and proceed
|
|
|
56
56
|
|
|
57
57
|
Read `{ccc}` from step-01 context.
|
|
58
58
|
|
|
59
|
-
**If `{ccc}` is false:** Set `{ccc_index_result: "none", ccc_indexed_path: null, ccc_last_indexed: null}`. Proceed directly to section 4 (Auto-Proceed) — no output, no messaging.
|
|
59
|
+
**If `{ccc}` is false:** Set `{ccc_index_result: "none", ccc_indexed_path: null, ccc_last_indexed: null, ccc_exclude_patterns: []}`. Proceed directly to section 4 (Auto-Proceed) — no output, no messaging.
|
|
60
60
|
|
|
61
61
|
**If `{ccc}` is true:** Continue to section 2.
|
|
62
62
|
|
|
@@ -64,17 +64,58 @@ Read `{ccc}` from step-01 context.
|
|
|
64
64
|
|
|
65
65
|
Read existing forge-tier.yaml at `{project-root}/_bmad/_memory/forger-sidecar/forge-tier.yaml` (if it exists from a previous run).
|
|
66
66
|
|
|
67
|
+
Read `staleness_threshold_hours` from `ccc_index.staleness_threshold_hours` in the existing forge-tier.yaml (default: 24 if not present or not a number). Use this value for the freshness check below.
|
|
68
|
+
|
|
67
69
|
Check the `ccc_index` section:
|
|
68
|
-
- If `ccc_index.indexed_path` matches `{project-root}` AND `ccc_index.status` is `"fresh"`:
|
|
69
|
-
- Check freshness: if `ccc_index.last_indexed` is within `staleness_threshold_hours`
|
|
70
|
+
- If `ccc_index.indexed_path` matches `{project-root}` AND `ccc_index.status` is `"fresh"` or `"created"`:
|
|
71
|
+
- Check freshness: if `ccc_index.last_indexed` is within `staleness_threshold_hours` of now → index is fresh
|
|
70
72
|
- Store `{ccc_index_result: "fresh", ccc_indexed_path: {project-root}, ccc_last_indexed: {existing timestamp}}`
|
|
71
|
-
-
|
|
73
|
+
- Set `{needs_reindex: false}` — proceed to section 2b (exclusions must still be configured)
|
|
72
74
|
|
|
73
75
|
- If `ccc_index.indexed_path` matches `{project-root}` but timestamp is older than threshold:
|
|
74
|
-
-
|
|
76
|
+
- Set `{needs_reindex: true}` — proceed to section 2b then section 3
|
|
75
77
|
|
|
76
78
|
- If `ccc_index` is missing, has null values, or path doesn't match:
|
|
77
|
-
-
|
|
79
|
+
- Set `{needs_reindex: true}` — proceed to section 2b then section 3
|
|
80
|
+
|
|
81
|
+
### 2b. Configure CCC Exclusions
|
|
82
|
+
|
|
83
|
+
SKF infrastructure and output directories must be excluded from the CCC index — they contain workflow instructions, build artifacts, and generated skills that pollute semantic search results with zero extraction value.
|
|
84
|
+
|
|
85
|
+
**Build the SKF exclusion list:**
|
|
86
|
+
|
|
87
|
+
1. Read `{project-root}/_bmad/_config/skf-manifest.yaml` to resolve configurable paths:
|
|
88
|
+
- `skills_output_folder` (default: `skills` if manifest is missing or field is absent)
|
|
89
|
+
- `forge_data_folder` (default: `forge-data` if manifest is missing or field is absent)
|
|
90
|
+
|
|
91
|
+
2. Assemble the exclusion patterns using `**/` prefix format (matching `.cocoindex_code/settings.yml` convention — e.g., `**/node_modules`):
|
|
92
|
+
- `**/_bmad` — SKF framework module (workflows, agents, knowledge files)
|
|
93
|
+
- `**/_bmad-output` — Build output artifacts
|
|
94
|
+
- `**/.claude` — Claude Code configuration
|
|
95
|
+
- `**/_skf-learn` — SKF learning materials
|
|
96
|
+
- `**/{skills_output_folder}` — Generated skill files (resolved from manifest)
|
|
97
|
+
- `**/{forge_data_folder}` — Compilation workspace (resolved from manifest)
|
|
98
|
+
|
|
99
|
+
3. Store `{ccc_exclude_patterns}` in context for step-02 to write into forge-tier.yaml.
|
|
100
|
+
|
|
101
|
+
**Apply exclusions to settings.yml:**
|
|
102
|
+
|
|
103
|
+
Check if `{project-root}/.cocoindex_code/settings.yml` exists. Set `{settings_yml_existed: true}` if it does, `{settings_yml_existed: false}` if not.
|
|
104
|
+
|
|
105
|
+
If `{settings_yml_existed}` is true (from a previous `ccc init` run):
|
|
106
|
+
|
|
107
|
+
1. Read `settings.yml`
|
|
108
|
+
2. For each pattern in `{ccc_exclude_patterns}`: if the pattern is NOT already present in `exclude_patterns`, append it and set `{exclusions_changed: true}`
|
|
109
|
+
3. If `{exclusions_changed}`: write the updated `settings.yml` back, set `{needs_reindex: true}` (new exclusions require re-indexing), display: "**CCC exclusions configured:** {count} SKF patterns applied to .cocoindex_code/settings.yml"
|
|
110
|
+
4. If no new patterns needed: display nothing (exclusions already configured)
|
|
111
|
+
|
|
112
|
+
This preserves any existing user customizations and default exclusions while ensuring SKF directories are filtered out.
|
|
113
|
+
|
|
114
|
+
If `{settings_yml_existed}` is false: the exclusions will be applied after `ccc init` in section 3.
|
|
115
|
+
|
|
116
|
+
**Flow decision:**
|
|
117
|
+
- If `{needs_reindex}` is true: proceed to section 3
|
|
118
|
+
- If `{needs_reindex}` is false: proceed to section 4 (Auto-Proceed)
|
|
78
119
|
|
|
79
120
|
### 3. Create or Refresh CCC Index
|
|
80
121
|
|
|
@@ -93,6 +134,15 @@ ccc init
|
|
|
93
134
|
|
|
94
135
|
**If init fails** (project may already be initialized): continue — this is not an error.
|
|
95
136
|
|
|
137
|
+
**Apply SKF exclusion patterns (if not already applied in section 2b):**
|
|
138
|
+
|
|
139
|
+
If `{settings_yml_existed}` is false (first-time setup — `ccc init` just created it), apply exclusions now:
|
|
140
|
+
|
|
141
|
+
1. Read `{project-root}/.cocoindex_code/settings.yml` (created by `ccc init`)
|
|
142
|
+
2. For each pattern in `{ccc_exclude_patterns}`: if the pattern is NOT already present in `exclude_patterns`, append it
|
|
143
|
+
3. Write the updated `settings.yml` back
|
|
144
|
+
4. Display: "**CCC exclusions configured:** {count} SKF patterns applied to .cocoindex_code/settings.yml"
|
|
145
|
+
|
|
96
146
|
Then run:
|
|
97
147
|
```bash
|
|
98
148
|
ccc index
|
|
@@ -102,8 +152,8 @@ ccc index
|
|
|
102
152
|
|
|
103
153
|
**If succeeds:**
|
|
104
154
|
- Run `ccc status` to get file count
|
|
105
|
-
- Store `{ccc_index_result: "created", ccc_indexed_path: {project-root}, ccc_last_indexed: {current ISO timestamp}, ccc_file_count: {count from status}}`
|
|
106
|
-
- Display: "**CCC index created.** {
|
|
155
|
+
- Store `{ccc_index_result: "created", ccc_indexed_path: {project-root}, ccc_last_indexed: {current ISO timestamp}, ccc_file_count: {count from ccc status}}`
|
|
156
|
+
- Display: "**CCC index created.** {ccc_file_count} files indexed for semantic discovery."
|
|
107
157
|
|
|
108
158
|
**If fails:**
|
|
109
159
|
- Store `{ccc_index_result: "failed", ccc_indexed_path: null, ccc_last_indexed: null}`
|
|
@@ -134,8 +184,8 @@ ONLY WHEN ccc index verification is complete (or step is skipped for ccc unavail
|
|
|
134
184
|
### ✅ SUCCESS:
|
|
135
185
|
|
|
136
186
|
- ccc unavailable: skipped silently with no output, context variables set to null/none
|
|
137
|
-
- ccc available with fresh index: verified freshness, skipped re-index, context variables set
|
|
138
|
-
- ccc available with stale/missing index: index created, context variables set with fresh timestamp
|
|
187
|
+
- ccc available with fresh index: verified freshness, exclusions configured, skipped re-index, context variables set
|
|
188
|
+
- ccc available with stale/missing index: exclusions configured, index created, context variables set with fresh timestamp
|
|
139
189
|
- ccc indexing fails: logged gracefully, workflow continues, context variables set to failed/null
|
|
140
190
|
- Auto-proceeded to step-02
|
|
141
191
|
|
|
@@ -143,8 +193,10 @@ ONLY WHEN ccc index verification is complete (or step is skipped for ccc unavail
|
|
|
143
193
|
|
|
144
194
|
- Displaying skip messages when ccc is unavailable
|
|
145
195
|
- Halting the workflow on ccc index failure
|
|
146
|
-
- Re-indexing when index is already fresh and path matches
|
|
196
|
+
- Re-indexing when index is already fresh and path matches (unless exclusion patterns changed)
|
|
147
197
|
- Writing forge-tier.yaml (that is step-02's responsibility)
|
|
148
198
|
- Not storing ccc index context variables for step-02
|
|
199
|
+
- Indexing without configuring SKF exclusion patterns in `.cocoindex_code/settings.yml`
|
|
200
|
+
- Overwriting user customizations in `.cocoindex_code/settings.yml` instead of appending
|
|
149
201
|
|
|
150
202
|
**Master Rule:** CCC indexing is always best-effort. Failures degrade gracefully. The workflow never halts over ccc issues.
|
|
@@ -41,7 +41,7 @@ Write the detected tool availability and calculated tier to forge-tier.yaml, cre
|
|
|
41
41
|
|
|
42
42
|
## CONTEXT BOUNDARIES:
|
|
43
43
|
|
|
44
|
-
- Available: {detected_tools}, {calculated_tier}, {previous_tier} from step-01; {ccc_index_result}, {ccc_indexed_path}, {ccc_last_indexed} from step-01b
|
|
44
|
+
- Available: {detected_tools}, {calculated_tier}, {previous_tier} from step-01; {ccc_index_result}, {ccc_indexed_path}, {ccc_last_indexed}, {ccc_file_count}, {ccc_exclude_patterns} from step-01b
|
|
45
45
|
- Focus: file I/O operations only
|
|
46
46
|
- Limits: do not modify preferences.yaml if it exists
|
|
47
47
|
- Dependencies: step-01 and step-01b must have completed with tool detection and CCC index results
|
|
@@ -78,6 +78,8 @@ ccc_index:
|
|
|
78
78
|
last_indexed: {ccc_last_indexed from step-01b, or ~}
|
|
79
79
|
status: {ccc_index_result from step-01b: "fresh"|"created"|"none"|"failed"}
|
|
80
80
|
staleness_threshold_hours: 24
|
|
81
|
+
file_count: {ccc_file_count from step-01b, or ~}
|
|
82
|
+
exclude_patterns: {ccc_exclude_patterns from step-01b, or []}
|
|
81
83
|
|
|
82
84
|
# CCC index registry (tracks which source paths have been indexed for skill workflows)
|
|
83
85
|
# PRESERVE existing entries on re-runs — see Note below
|
|
@@ -88,7 +90,7 @@ ccc_index_registry: {preserved from existing forge-tier.yaml, or [] if first run
|
|
|
88
90
|
qmd_collections: {preserved from existing forge-tier.yaml, or [] if first run}
|
|
89
91
|
```
|
|
90
92
|
|
|
91
|
-
**Note on re-runs:** The `qmd_collections`, `ccc_index_registry` arrays, and `staleness_threshold_hours` value must be preserved across re-runs. Before overwriting forge-tier.yaml, read these existing values and re-inject them into the new write. These values are populated by create-skill workflows or customized by users and must not be reset.
|
|
93
|
+
**Note on re-runs:** The `qmd_collections`, `ccc_index_registry` arrays, and `staleness_threshold_hours` value must be preserved across re-runs. Before overwriting forge-tier.yaml, read these existing values and re-inject them into the new write. These values are populated by create-skill workflows or customized by users and must not be reset. Note: `exclude_patterns` is NOT preserved — it is always written fresh from `{ccc_exclude_patterns}` computed by step-01b.
|
|
92
94
|
|
|
93
95
|
**This file is ALWAYS overwritten** on every run — it reflects current tool state.
|
|
94
96
|
|
|
@@ -150,7 +152,7 @@ ONLY WHEN forge-tier.yaml has been written successfully and preferences.yaml exi
|
|
|
150
152
|
|
|
151
153
|
### ✅ SUCCESS:
|
|
152
154
|
|
|
153
|
-
- forge-tier.yaml written with accurate tool booleans (including ccc), tier, timestamp, ccc_index state, and preserved qmd_collections/ccc_index_registry arrays
|
|
155
|
+
- forge-tier.yaml written with accurate tool booleans (including ccc), tier, timestamp, ccc_index state (including exclude_patterns), and preserved qmd_collections/ccc_index_registry arrays
|
|
154
156
|
- preferences.yaml exists (created with defaults on first run, preserved on re-run)
|
|
155
157
|
- forge-data/ directory exists (created or pre-existing)
|
|
156
158
|
- Auto-proceeded to step-03
|
|
@@ -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}`:
|
|
@@ -139,6 +139,8 @@ This helps the merge step (section 4) prioritize which changes are most likely t
|
|
|
139
139
|
|
|
140
140
|
CCC failures: skip ranking silently, all changes treated equally.
|
|
141
141
|
|
|
142
|
+
**Note on remote sources:** If `source_root` is an ephemeral clone (remote source), the clone path is not indexed by CCC. The search will return empty results and semantic ranking will be skipped. This is expected — deferred CCC indexing is implemented in create-skill step-03 but not in update-skill. All changes are treated equally for remote sources.
|
|
143
|
+
|
|
142
144
|
**IF `tools.ccc` is false:** Skip this section silently.
|
|
143
145
|
|
|
144
146
|
### 3. Deep Tier QMD Enrichment (Conditional)
|