bmad-module-skill-forge 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/README.md +3 -2
  2. package/docs/agents.md +3 -0
  3. package/docs/concepts.md +24 -6
  4. package/docs/examples.md +31 -2
  5. package/docs/getting-started.md +11 -0
  6. package/docs/{architecture.md → how-it-works.md} +49 -25
  7. package/docs/index.md +2 -2
  8. package/docs/workflows.md +6 -6
  9. package/package.json +2 -2
  10. package/src/agents/forger.agent.yaml +1 -1
  11. package/src/forger/forge-tier.yaml +17 -1
  12. package/src/forger/preferences.yaml +1 -1
  13. package/src/knowledge/agentskills-spec.md +25 -0
  14. package/src/knowledge/ccc-bridge.md +110 -0
  15. package/src/knowledge/confidence-tiers.md +3 -3
  16. package/src/knowledge/manual-section-integrity.md +8 -0
  17. package/src/knowledge/overview.md +4 -2
  18. package/src/knowledge/progressive-capability.md +12 -4
  19. package/src/knowledge/provenance-tracking.md +13 -0
  20. package/src/knowledge/qmd-registry.md +14 -0
  21. package/src/knowledge/skf-knowledge-index.csv +5 -3
  22. package/src/knowledge/skill-lifecycle.md +2 -2
  23. package/src/knowledge/split-body-strategy.md +41 -0
  24. package/src/module-help.csv +1 -1
  25. package/src/module.yaml +1 -1
  26. package/src/workflows/README.md +1 -1
  27. package/src/workflows/analyze-source/data/skill-brief-schema.md +3 -1
  28. package/src/workflows/analyze-source/data/unit-detection-heuristics.md +27 -0
  29. package/src/workflows/analyze-source/steps-c/step-01-init.md +2 -2
  30. package/src/workflows/analyze-source/steps-c/step-02-scan-project.md +1 -1
  31. package/src/workflows/analyze-source/steps-c/step-03-identify-units.md +1 -1
  32. package/src/workflows/analyze-source/steps-c/step-04-map-and-detect.md +9 -4
  33. package/src/workflows/analyze-source/steps-c/step-05-recommend.md +1 -1
  34. package/src/workflows/analyze-source/steps-c/step-06-generate-briefs.md +1 -1
  35. package/src/workflows/analyze-source/validation-report.md +2 -2
  36. package/src/workflows/analyze-source/workflow-plan-analyze-source.md +1 -1
  37. package/src/workflows/audit-skill/data/drift-report-template.md +6 -6
  38. package/src/workflows/audit-skill/steps-c/step-01-init.md +4 -2
  39. package/src/workflows/audit-skill/steps-c/step-02-re-index.md +18 -1
  40. package/src/workflows/audit-skill/steps-c/step-03-structural-diff.md +14 -0
  41. package/src/workflows/audit-skill/steps-c/step-04-semantic-diff.md +5 -5
  42. package/src/workflows/audit-skill/validation-report.md +3 -3
  43. package/src/workflows/audit-skill/workflow-plan-audit-skill.md +2 -2
  44. package/src/workflows/audit-skill/workflow.md +1 -1
  45. package/src/workflows/brief-skill/data/scope-templates.md +4 -0
  46. package/src/workflows/brief-skill/data/skill-brief-schema.md +7 -3
  47. package/src/workflows/brief-skill/steps-c/step-01-gather-intent.md +3 -3
  48. package/src/workflows/brief-skill/steps-c/step-02-analyze-target.md +15 -0
  49. package/src/workflows/brief-skill/steps-c/step-03-scope-definition.md +12 -0
  50. package/src/workflows/create-skill/data/compile-assembly-rules.md +43 -2
  51. package/src/workflows/create-skill/data/extraction-patterns-tracing.md +110 -0
  52. package/src/workflows/create-skill/data/extraction-patterns.md +41 -39
  53. package/src/workflows/create-skill/data/skill-sections.md +31 -5
  54. package/src/workflows/create-skill/steps-c/step-01-load-brief.md +5 -3
  55. package/src/workflows/create-skill/steps-c/step-02-ecosystem-check.md +2 -2
  56. package/src/workflows/create-skill/steps-c/step-02b-ccc-discover.md +157 -0
  57. package/src/workflows/create-skill/steps-c/step-03-extract.md +32 -2
  58. package/src/workflows/create-skill/steps-c/step-03b-fetch-temporal.md +5 -5
  59. package/src/workflows/create-skill/steps-c/step-04-enrich.md +8 -8
  60. package/src/workflows/create-skill/steps-c/step-05-compile.md +6 -2
  61. package/src/workflows/create-skill/steps-c/step-06-validate.md +8 -9
  62. package/src/workflows/create-skill/steps-c/step-07-generate-artifacts.md +46 -1
  63. package/src/workflows/create-skill/steps-c/step-08-report.md +1 -0
  64. package/src/workflows/create-skill/validation-report.md +1 -1
  65. package/src/workflows/create-skill/workflow-plan-create-skill.md +4 -2
  66. package/src/workflows/create-skill/workflow.md +1 -1
  67. package/src/workflows/create-stack-skill/data/stack-skill-template.md +1 -1
  68. package/src/workflows/create-stack-skill/steps-c/step-01-init.md +3 -2
  69. package/src/workflows/create-stack-skill/steps-c/step-05-detect-integrations.md +10 -0
  70. package/src/workflows/create-stack-skill/steps-c/step-06-compile-stack.md +2 -2
  71. package/src/workflows/create-stack-skill/steps-c/step-08-validate.md +1 -1
  72. package/src/workflows/create-stack-skill/validation-report.md +1 -1
  73. package/src/workflows/create-stack-skill/workflow-plan-create-stack-skill.md +2 -2
  74. package/src/workflows/create-stack-skill/workflow.md +1 -1
  75. package/src/workflows/export-skill/data/snippet-format.md +1 -1
  76. package/src/workflows/export-skill/steps-c/step-01-load-skill.md +1 -1
  77. package/src/workflows/export-skill/steps-c/step-02-package.md +8 -4
  78. package/src/workflows/export-skill/steps-c/step-03-generate-snippet.md +3 -1
  79. package/src/workflows/export-skill/workflow-plan-export-skill.md +1 -1
  80. package/src/workflows/quick-skill/data/skill-template.md +8 -0
  81. package/src/workflows/quick-skill/steps-c/step-02-ecosystem-check.md +1 -3
  82. package/src/workflows/quick-skill/steps-c/step-04-compile.md +3 -2
  83. package/src/workflows/setup-forge/data/tier-rules.md +16 -6
  84. package/src/workflows/setup-forge/steps-c/step-01-detect-and-tier.md +32 -15
  85. package/src/workflows/setup-forge/steps-c/step-01b-ccc-index.md +148 -0
  86. package/src/workflows/setup-forge/steps-c/step-02-write-config.md +24 -6
  87. package/src/workflows/setup-forge/steps-c/step-03-auto-index.md +29 -6
  88. package/src/workflows/setup-forge/steps-c/step-04-report.md +14 -2
  89. package/src/workflows/setup-forge/validation-report.md +1 -1
  90. package/src/workflows/setup-forge/workflow-plan-setup-forge.md +11 -9
  91. package/src/workflows/setup-forge/workflow.md +1 -1
  92. package/src/workflows/test-skill/data/scoring-rules.md +14 -0
  93. package/src/workflows/test-skill/steps-c/step-01-init.md +2 -2
  94. package/src/workflows/test-skill/steps-c/step-03-coverage-check.md +3 -1
  95. package/src/workflows/test-skill/steps-c/step-04-coherence-check.md +4 -1
  96. package/src/workflows/test-skill/steps-c/step-04b-external-validators.md +7 -3
  97. package/src/workflows/test-skill/steps-c/step-05-score.md +1 -1
  98. package/src/workflows/test-skill/steps-c/step-06-report.md +27 -0
  99. package/src/workflows/test-skill/templates/test-report-template.md +3 -0
  100. package/src/workflows/test-skill/validation-report.md +2 -2
  101. package/src/workflows/test-skill/workflow-plan-test-skill.md +2 -2
  102. package/src/workflows/update-skill/steps-c/step-01-init.md +3 -2
  103. package/src/workflows/update-skill/steps-c/step-02-detect-changes.md +11 -0
  104. package/src/workflows/update-skill/steps-c/step-03-re-extract.md +19 -2
  105. package/src/workflows/update-skill/steps-c/step-04-merge.md +8 -0
  106. package/src/workflows/update-skill/steps-c/step-05-validate.md +1 -1
  107. package/src/workflows/update-skill/steps-c/step-06-write.md +7 -2
  108. package/src/workflows/update-skill/validation-report.md +1 -1
  109. package/src/workflows/update-skill/workflow-plan-update-skill.md +1 -1
  110. package/tools/cli/commands/status.js +2 -1
@@ -134,9 +134,26 @@ Append temporal metadata to each export in the snapshot.
134
134
  Log: "No QMD extraction collection found for {skill_name}. Temporal enrichment skipped. Re-run [CS] Create Skill to generate the collection."
135
135
  Continue without T2 enrichment — this is not an error.
136
136
 
137
- **IF forge tier is Quick or Forge:**
137
+ **IF forge tier is Quick, Forge, or Forge+:**
138
138
  Skip this section. Temporal context requires Deep tier.
139
139
 
140
+ ### 4b. CCC Rename Detection (Forge+ and Deep with ccc)
141
+
142
+ **IF `tools.ccc` is true in forge-tier.yaml:**
143
+
144
+ For each export in the skill baseline that was NOT found at its recorded file path during re-extraction (potential "deleted" export):
145
+
146
+ 1. Run `ccc_bridge.search("{export_name}", source_root, top_k=5)` to find candidate current locations
147
+ 2. If CCC returns files containing the export name:
148
+ - Run ast-grep verification on each candidate file
149
+ - If verified at a new location: reclassify from "deleted" to "moved" with the new file:line reference
150
+ - This reduces false-positive structural drift findings where exports were relocated, not removed
151
+ 3. If CCC returns no results or verification fails: keep the "deleted" classification
152
+
153
+ CCC failures: skip rename detection silently, proceed with standard structural diff.
154
+
155
+ **IF `tools.ccc` is false:** Skip this section silently.
156
+
140
157
  ### 5. Validate Extraction Completeness
141
158
 
142
159
  "**Extraction complete.**
@@ -108,6 +108,20 @@ For each changed export, record:
108
108
  - What changed (signature / type / location)
109
109
  - Confidence tier
110
110
 
111
+ ### 4b. Detect Script/Asset Drift
112
+
113
+ **Only execute if provenance-map.json contains `file_entries`.**
114
+
115
+ For each entry in `file_entries`:
116
+ 1. Locate the source file at the original `source_file` path
117
+ 2. Compute current SHA-256 content hash
118
+ 3. Compare against stored `content_hash`
119
+ - CHANGED: hash mismatch → record as script/asset content drift
120
+ - MISSING: source file no longer exists → record as removed
121
+ - NEW: source contains files matching script/asset patterns not in `file_entries` → record as added
122
+
123
+ Append results to the Structural Drift section as "### Script/Asset Drift ({count})".
124
+
111
125
  ### 5. Compile Structural Drift Section
112
126
 
113
127
  Append to {outputFile}:
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: 'step-04-semantic-diff'
3
- description: 'Compare QMD knowledge context for meaning-level changes (Deep tier only, skip at Quick/Forge)'
3
+ description: 'Compare QMD knowledge context for meaning-level changes (Deep tier only, skip at Quick/Forge/Forge+)'
4
4
 
5
5
  nextStepFile: './step-05-severity-classify.md'
6
6
  outputFile: '{forge_data_folder}/{skill_name}/drift-report-{timestamp}.md'
@@ -10,7 +10,7 @@ outputFile: '{forge_data_folder}/{skill_name}/drift-report-{timestamp}.md'
10
10
 
11
11
  ## STEP GOAL:
12
12
 
13
- Compare QMD knowledge context between the original skill creation and current state to detect meaning-level changes that structural diff cannot catch. This step executes ONLY at Deep tier — at Quick and Forge tiers, it appends a skip notice and auto-proceeds.
13
+ Compare QMD knowledge context between the original skill creation and current state to detect meaning-level changes that structural diff cannot catch. This step executes ONLY at Deep tier — at Quick, Forge, and Forge+ tiers, it appends a skip notice and auto-proceeds.
14
14
 
15
15
  ## MANDATORY EXECUTION RULES (READ FIRST):
16
16
 
@@ -35,7 +35,7 @@ Compare QMD knowledge context between the original skill creation and current st
35
35
  - 🚫 FORBIDDEN to repeat structural findings from Step 03
36
36
  - 💬 Use subprocess Pattern 3 (data operations) when available for QMD queries
37
37
  - ⚙️ If subprocess unavailable, query QMD in main thread
38
- - 🔀 CONDITIONAL: Skip entire analysis at Quick/Forge tier — append skip notice only
38
+ - 🔀 CONDITIONAL: Skip entire analysis at Quick/Forge/Forge+ tier — append skip notice only
39
39
 
40
40
  ## EXECUTION PROTOCOLS:
41
41
 
@@ -57,7 +57,7 @@ Compare QMD knowledge context between the original skill creation and current st
57
57
 
58
58
  ### 1. Check Forge Tier
59
59
 
60
- **IF forge tier is Quick or Forge:**
60
+ **IF forge tier is Quick, Forge, or Forge+:**
61
61
 
62
62
  Append to {outputFile}:
63
63
 
@@ -179,7 +179,7 @@ ONLY WHEN the ## Semantic Drift section (or skip notice) has been appended to {o
179
179
 
180
180
  ### ✅ SUCCESS:
181
181
 
182
- - Forge tier checked FIRST — skip gracefully at Quick/Forge
182
+ - Forge tier checked FIRST — skip gracefully at Quick/Forge/Forge+
183
183
  - Deep tier: QMD knowledge context queried and compared
184
184
  - All semantic findings have T2 confidence labels
185
185
  - Findings clearly distinguished from structural drift (T1)
@@ -413,7 +413,7 @@ The audit-skill workflow is a well-designed, cohesive 6-step pipeline that achie
413
413
  ### Strengths
414
414
 
415
415
  1. **Zero-hallucination principle** enforced consistently — every finding traces to actual code
416
- 2. **Graceful degradation** at every level — tier-aware (Quick/Forge/Deep), missing provenance (degraded mode)
416
+ 2. **Graceful degradation** at every level — tier-aware (Quick/Forge/Forge+/Deep), missing provenance (degraded mode)
417
417
  3. **Structured output** with file:line citations and confidence tier labels on all findings
418
418
  4. **Actionable remediation** — specific suggestions per finding (what to change, where, why)
419
419
  5. **Workflow chaining** — update-skill recommendation when CRITICAL/HIGH drift found
@@ -441,7 +441,7 @@ The audit-skill workflow is a well-designed, cohesive 6-step pipeline that achie
441
441
  |-------------|-------------|---------|--------|
442
442
  | Drift detection between skill and source | workflow.md + all 6 steps | High | ✅ |
443
443
  | Ferris Audit mode | workflow.md + all step role reinforcements | High | ✅ |
444
- | Tier-aware depth (Quick/Forge/Deep) | Steps 01-04 adapt per tier | High | ✅ |
444
+ | Tier-aware depth (Quick/Forge/Forge+/Deep) | Steps 01-04 adapt per tier | High | ✅ |
445
445
  | Drift report with severity levels | Steps 03-06 build categorized report | High | ✅ |
446
446
 
447
447
  ### Classification Validation
@@ -534,7 +534,7 @@ None identified. All requirements from the plan are fully implemented.
534
534
  ### Key Strengths
535
535
 
536
536
  - Zero-hallucination principle enforced consistently throughout
537
- - Graceful tier-aware degradation (Quick/Forge/Deep)
537
+ - Graceful tier-aware degradation (Quick/Forge/Forge+/Deep)
538
538
  - Well-chosen subprocess patterns with graceful fallbacks
539
539
  - Clean data flow: provenance → extraction → diff → classification → report
540
540
  - Actionable remediation suggestions with workflow chaining
@@ -54,7 +54,7 @@ Drift report with severity levels (added/removed/changed exports, breaking chang
54
54
  ### Key Instructions to LLM
55
55
 
56
56
  - Primary agent: Ferris (Audit mode)
57
- - Tiered operation: Forge tier (structural only) vs Deep tier (full semantic + QMD)
57
+ - Tiered operation: Forge/Forge+ tier (structural, with optional CCC augmentation) vs Deep tier (full semantic + QMD)
58
58
  - The spec references AST diff for structural comparison and QMD for semantic context
59
59
  - CI integration is noted as optional export (ADR-A decision)
60
60
 
@@ -70,7 +70,7 @@ Drift report with severity levels (added/removed/changed exports, breaking chang
70
70
  - Document-producing output aligns with drift report use case
71
71
 
72
72
  **What needs improvement (fix during build):**
73
- - **Missing Quick tier path** — All SKF workflows support Quick/Forge/Deep with graceful degradation; Quick tier needs text-diff fallback
73
+ - **Missing Quick tier path** — All SKF workflows support Quick/Forge/Forge+/Deep with graceful degradation; Quick tier needs text-diff fallback
74
74
  - **No provenance map format specification** — Step 01 loads it, but must reference known `provenance-map.json` from create-skill's `forge-data/{name}/` output
75
75
  - **No confidence tier labels (T1/T2/T3)** — Every SKF workflow uses these for traceability; drift findings need confidence scoring
76
76
  - **Step 04 conditional skip** — semantic-diff is Deep-only but spec has no skip logic or degradation behavior for Forge/Quick tiers
@@ -24,7 +24,7 @@ This uses **step-file architecture** for disciplined execution:
24
24
  - **Sequential Enforcement**: Sequence within the step files must be completed in order, no skipping or optimization allowed
25
25
  - **State Tracking**: Document progress in output file frontmatter using `stepsCompleted` array
26
26
  - **Append-Only Building**: Build the drift report by appending sections as directed to the output file
27
- - **Tier-Aware Execution**: Adapt analysis depth based on detected forge tier (Quick/Forge/Deep) with graceful degradation
27
+ - **Tier-Aware Execution**: Adapt analysis depth based on detected forge tier (Quick/Forge/Forge+/Deep) with graceful degradation
28
28
 
29
29
  ### Step Processing Rules
30
30
 
@@ -58,3 +58,7 @@ Prompt: "Which of these would you like to include? (Enter numbers, or 'all'):"
58
58
 
59
59
  Exclusions will include all internal implementation files, tests, and utilities.
60
60
  Prompt: "Any additional items you'd like to include or exclude?"
61
+
62
+ ## Scripts & Assets Detection (Optional Refinement)
63
+
64
+ When `scripts_intent` or `assets_intent` is `detect` (default), SKF auto-detects from source directories matching: `scripts/`, `bin/`, `tools/`, `cli/` (for scripts) and `assets/`, `templates/`, `schemas/`, `configs/`, `examples/` (for assets). Detection applies to all scope types except `docs-only`.
@@ -10,7 +10,7 @@
10
10
  | language | string | Primary programming language | Must be detected or user-specified |
11
11
  | scope | object | Inclusion/exclusion boundaries | Must have type + at least one pattern |
12
12
  | description | string | What this skill covers | 1-3 sentences |
13
- | forge_tier | string | Compilation tier | One of: quick, forge, deep |
13
+ | forge_tier | string | Compilation tier | One of: quick, forge, forge+, deep |
14
14
  | created | string | Creation date | ISO date format |
15
15
  | created_by | string | User who created the brief | From config user_name |
16
16
 
@@ -20,6 +20,8 @@
20
20
  |-------|------|-------------|------------|
21
21
  | source_type | string | Source mode: `source` or `docs-only` | Default `source`. When `docs-only`: `source_repo` optional, `doc_urls` required |
22
22
  | doc_urls | array | Documentation URLs for T3 content | Each entry: `{url, label}`. Required when `source_type: "docs-only"` |
23
+ | `scripts_intent` | string | Describes whether scripts should be extracted. Values: `detect` (auto-detect from source — default when absent), `none` (skip scripts), or a free-text description of expected scripts (e.g., "CLI validation tools in bin/"). |
24
+ | `assets_intent` | string | Describes whether assets should be extracted. Values: `detect` (auto-detect from source — default when absent), `none` (skip assets), or a free-text description of expected assets (e.g., "JSON schemas in schemas/"). |
23
25
 
24
26
  When `source_type: "docs-only"`:
25
27
  - `source_repo` becomes optional (set to doc site URL for reference)
@@ -65,7 +67,7 @@ source_type: "source" # "source" (default) or "docs-only"
65
67
  source_repo: "{github-url-or-local-path}"
66
68
  language: "{detected-language}"
67
69
  description: "{brief-description}"
68
- forge_tier: "{quick|forge|deep}"
70
+ forge_tier: "{quick|forge|forge+|deep}"
69
71
  created: "{date}"
70
72
  created_by: "{user_name}"
71
73
  scope:
@@ -79,6 +81,8 @@ scope:
79
81
  # doc_urls:
80
82
  # - url: "https://docs.example.com/api"
81
83
  # label: "API Reference"
84
+ # scripts_intent: detect # Optional: detect | none | description
85
+ # assets_intent: detect # Optional: detect | none | description
82
86
  ---
83
87
  ```
84
88
 
@@ -112,6 +116,6 @@ Created by: {created_by}
112
116
  3. `language` must be a recognized programming language
113
117
  4. `scope.type` must be one of the three defined types
114
118
  5. `scope.include` must have at least one pattern
115
- 6. `forge_tier` must match the tier from forge-tier.yaml (or default to quick)
119
+ 6. `forge_tier` must be one of: quick, forge, forge+, deep (must match the tier from forge-tier.yaml, or default to quick)
116
120
  7. When `source_type: "docs-only"`: `doc_urls` must have >= 1 entry, `source_repo` becomes optional
117
121
  8. Each `doc_urls` entry must have a valid `url` field
@@ -3,7 +3,7 @@ name: 'step-01-gather-intent'
3
3
  description: 'Initialize brief-skill workflow, discover forge tier, and gather user intent for skill creation'
4
4
 
5
5
  nextStepFile: './step-02-analyze-target.md'
6
- forgeTierFile: '{project-root}/_bmad/_memory/forger-sidecar/forge-tier.yaml'
6
+ forgeTierFile: '{sidecar_path}/forge-tier.yaml'
7
7
  ---
8
8
 
9
9
  # Step 1: Gather Intent
@@ -61,10 +61,10 @@ To initialize the brief-skill workflow by discovering the forge tier configurati
61
61
  Attempt to load `{forgeTierFile}`:
62
62
 
63
63
  **If found:**
64
- - Read the tier level (quick, forge, or deep)
64
+ - Read the tier level (quick, forge, forge+, or deep)
65
65
  - Note available tools for scoping guidance later
66
66
 
67
- **Apply tier override:** Read `{sidecar_path}/preferences.yaml`. If `tier_override` is set and is a valid tier value (Quick, Forge, or Deep), use it instead of the detected tier.
67
+ **Apply tier override:** Read `{sidecar_path}/preferences.yaml`. If `tier_override` is set and is a valid tier value (Quick, Forge, Forge+, or Deep), use it instead of the detected tier.
68
68
 
69
69
  **If not found:**
70
70
  - Display: "**Note:** No forge tier configuration found. Defaulting to Quick tier. Run **setup-forge** first for full capabilities."
@@ -131,6 +131,21 @@ Based on detected language, identify public API surface:
131
131
  **Detected Exports/Entry Points:**
132
132
  {numbered list of public-facing items found}"
133
133
 
134
+ **Semantic Signals (Forge+ and Deep with ccc only):**
135
+
136
+ If `tools.ccc` is true in forge-tier.yaml, supplement the module listing with a semantic discovery pass:
137
+
138
+ Run `ccc_bridge.search("{repo_name} public API exports modules", source_path, top_k=10)`.
139
+
140
+ If results are returned, display:
141
+
142
+ "**Semantic Signals (ccc):**
143
+ {numbered list of file:snippet pairs from CCC results — top 5 most relevant}"
144
+
145
+ This supplements — never replaces — the explicit module list above. CCC may surface non-obvious entry points (dynamically constructed exports, re-export chains) that static directory analysis misses.
146
+
147
+ If CCC is unavailable or returns no results: skip this subsection silently.
148
+
134
149
  ### 5. Report Analysis Summary
135
150
 
136
151
  Present the complete analysis:
@@ -135,6 +135,18 @@ Does this look right? You can adjust before we continue."
135
135
 
136
136
  Wait for confirmation. Make adjustments if requested.
137
137
 
138
+ ### 5b. Scripts & Assets Intent (Optional)
139
+
140
+ **Only ask when `scope.type` is `full-library` or `specific-modules` (skip for `public-api` and `docs-only`).**
141
+
142
+ "Does this library include executable scripts (CLI tools, validation scripts, setup helpers) or static assets (config templates, JSON schemas, example configs) that should be packaged with the skill?"
143
+
144
+ - **[D] Auto-detect** from source (default) — SKF will scan for `scripts/`, `bin/`, `assets/`, `templates/`, `schemas/` directories
145
+ - **[N] None expected** — skip script/asset detection
146
+ - Or describe what you expect (free text)
147
+
148
+ Record the response as `scripts_intent` and `assets_intent` in the brief. Default to `detect` if user does not respond or skips.
149
+
138
150
  ### 6. Present MENU OPTIONS
139
151
 
140
152
  Display: **Select an Option:** [A] Advanced Elicitation [P] Party Mode [C] Continue to Brief Confirmation
@@ -14,8 +14,8 @@ description: >
14
14
 
15
15
  **Frontmatter rules:**
16
16
 
17
- - `name`: lowercase alphanumeric + hyphens only, must match the skill output directory name
18
- - `description`: non-empty, max 1024 chars, optimized for agent discovery
17
+ - `name`: lowercase alphanumeric + hyphens only, must match the skill output directory name. Prefer gerund form (`processing-pdfs`, `analyzing-spreadsheets`) for clarity.
18
+ - `description`: non-empty, max 1024 chars, optimized for agent discovery. **MUST use third-person voice** ("Processes Excel files..." not "I can help you..." or "You can use this to..."). Inconsistent point-of-view causes discovery problems since the description is injected into the system prompt.
19
19
  - Only `name` and `description` in frontmatter — `version` and `author` go in metadata.json
20
20
  - No other frontmatter fields for standard skills (only `name`, `description`, `license`, `compatibility`, `metadata`, `allowed-tools` are permitted by spec)
21
21
 
@@ -77,6 +77,14 @@ These sections form the essential standalone body. Target: **under 300 lines tot
77
77
  - Basic CLI commands if the library has a CLI interface
78
78
  - Skip if no CLI exists
79
79
 
80
+ **Section 7b — Scripts & Assets (~10 lines, if applicable):**
81
+ - Manifest table of included scripts with filename, one-line purpose, and provenance citation
82
+ - Manifest table of included assets with filename, one-line purpose, and provenance citation
83
+ - Each entry: `scripts/{filename}` or `assets/{filename}`, purpose, `[SRC:{source_path}:L1]`
84
+ - Include a note: "Load scripts from `scripts/` and assets from `assets/` when directed by the instructions above."
85
+ - **Skip entirely** when no scripts or assets detected in extraction inventory — do not emit an empty section
86
+ - Like Sections 4b and 7, parsers must treat this section as optional
87
+
80
88
  **Section 8 — Manual Sections:**
81
89
  - Seed empty `<!-- [MANUAL] -->` markers:
82
90
  ```markdown
@@ -108,3 +116,36 @@ Do NOT repeat Tier 1's name/purpose/key-params table format in Tier 2. Tier 2 is
108
116
  4. If Tier 1 alone exceeds 300 lines, reduce Key API Summary and Architecture at a Glance
109
117
  5. Tier 1 sections are kept short enough that `split-body` targets the larger Tier 2 sections (`## Full ...` headings) instead
110
118
  6. After split-body, SKILL.md must still contain all Tier 1 sections with actionable content
119
+
120
+ ### Reference File Rules
121
+
122
+ - **Table of contents required** for any reference file exceeding 100 lines — include a `## Contents` section at the top listing all sub-sections. This ensures agents can see the full scope even when previewing with partial reads.
123
+ - One file per major function group or type — group by module, file, or functional area
124
+ - Name files descriptively: `form_validation_rules.md`, not `doc2.md`
125
+
126
+ ### Content Quality Rules
127
+
128
+ These rules apply to all content assembled in SKILL.md and reference files.
129
+
130
+ **Degrees of freedom:** Match instruction specificity to the task's fragility and variability:
131
+ - **High freedom** (text guidance): When multiple approaches are valid and context determines the best one. Example: code review patterns, architecture suggestions.
132
+ - **Medium freedom** (pseudocode/parameterized scripts): When a preferred pattern exists but variation is acceptable. Example: configuration templates, report generation.
133
+ - **Low freedom** (exact scripts, no parameters): When operations are fragile and consistency is critical. Example: database migrations, deployment sequences. Use "Run exactly this" language.
134
+
135
+ **Consistent terminology:** Choose one term per concept and use it throughout the skill. Do not mix synonyms (e.g., "API endpoint" vs "URL" vs "route", or "field" vs "box" vs "element"). Consistency helps agents understand and follow instructions deterministically.
136
+
137
+ **Avoid time-sensitive information:** Do not include date-conditional instructions ("If before August 2025, use the old API"). Instead, document the current method and place deprecated patterns in a collapsible "Old patterns" section with the deprecation date.
138
+
139
+ **Template and examples patterns:**
140
+ - **For strict requirements** (API responses, data formats): Provide an exact template with "ALWAYS use this exact structure" language.
141
+ - **For flexible guidance** (reports, analysis): Provide a sensible default template with "Adjust sections as needed" language.
142
+ - **Input/output examples:** When output quality depends on seeing examples and concrete pairs exist in source tests or official docs, include 2-3 input/output pairs sourced from those tests or docs. Examples help agents understand desired style and detail more clearly than descriptions alone. If no examples exist in source, note the gap rather than fabricating pairs — zero hallucination applies.
143
+
144
+ **Workflow checklist pattern:** When a skill includes multi-step workflows, provide a copy-paste checklist that agents can track progress against:
145
+ ```markdown
146
+ Copy this checklist and track your progress:
147
+ - [ ] Step 1: {action}
148
+ - [ ] Step 2: {action}
149
+ ```
150
+
151
+ **Verifiable intermediate outputs:** For skills involving batch operations, destructive changes, or complex validation, recommend the plan-validate-execute pattern: create a structured plan file (e.g., `changes.json`), validate it with a script, then execute. This catches errors before changes are applied.
@@ -0,0 +1,110 @@
1
+ # Extraction Patterns: Tracing and File-Level Extraction
2
+
3
+ This file covers re-export tracing protocols and script/asset file-level extraction patterns. For core tier strategies and AST extraction protocol, see `extraction-patterns.md`.
4
+
5
+ ---
6
+
7
+ ## Re-Export Tracing
8
+
9
+ After initial AST extraction, some top-level exports may resolve to **module imports** rather than direct function definitions. This is common in Python libraries that use `__init__.py` re-exports for a clean public API.
10
+
11
+ **Detection heuristic:** For each top-level export from `__init__.py` (or equivalent entry point), check if the import path resolves to a directory (contains `__init__.py`) rather than a `.py` file with a matching `def` or `class`. If the initial AST scan found no function/class definition for a known public export, it is likely a module re-export.
12
+
13
+ **Tracing protocol:**
14
+
15
+ 1. Read the entry point file (e.g., `{package}/__init__.py`) and extract all `from .X import Y` statements
16
+ 2. For each import where Y was NOT found by the initial AST scan:
17
+ - Check if the import path resolves to a directory (e.g., `{package}/api/v1/delete/` exists with `__init__.py`)
18
+ - If directory: read its `__init__.py` to find the actual re-exported symbol
19
+ - **Handle aliases:** Check for `from .module import A as B` patterns in the intermediate `__init__.py`. If the parent imports `B`, trace through to `A` in `.module`. If the parent imports `A` but the `__init__.py` only exports it as `B` (via `from .module import A as B`), match by original name `A` and note the alias
20
+ - Trace the symbol to its definition file and run AST extraction on that file
21
+ 3. Cite the actual definition location: `[AST:{definition_file}:L{line}]`
22
+
23
+ **Examples:**
24
+
25
+ ```python
26
+ # Module re-export — follow required
27
+ from .api.v1.delete import delete # delete/ is a directory → read delete/__init__.py
28
+
29
+ # Direct function import — no follow needed
30
+ from .api.v1.add.add import add # add.py exists with def add()
31
+
32
+ # Aliased re-export — follow through alias
33
+ # In cognee/api/v1/visualize/__init__.py:
34
+ # from .start_visualization_server import visualization_server
35
+ # In cognee/__init__.py:
36
+ # from .api.v1.visualize import start_visualization_server
37
+ # → Match start_visualization_server against both definition names AND alias names
38
+ # in the intermediate __init__.py to resolve the chain
39
+ ```
40
+
41
+ **Unresolvable imports:** If the import statement is a star-import (`from .X import *`) or a conditional import (`try`/`except`), the symbol cannot be reliably traced via this protocol. Record it with `[SRC:{package}/__init__.py:L{line}]` (T1-low) and a note: "star/conditional import — manual trace required."
42
+
43
+ **Scope limit:** Only trace re-exports for symbols listed in the top-level entry point's public API. Do not recursively trace beyond one level of `__init__.py` indirection. If a re-export cannot be resolved after one level, record it with a `[SRC:{package}/__init__.py:L{line}]` citation (T1-low) from the import statement itself.
44
+
45
+ **Other languages:** JS/TS barrel files (`index.ts` with `export { X } from './module'`) follow the same principle — trace the re-export to the definition file. Rust `pub use` and Go package-level re-exports are less common but follow the same heuristic when encountered.
46
+
47
+ ---
48
+
49
+ ## Script/Asset Extraction Patterns
50
+
51
+ Scripts and assets are file-level artifacts, not code exports. They follow the **file-copy extraction method** — detected in source, copied with provenance citations.
52
+
53
+ ### Detection Heuristics
54
+
55
+ **Script directories:** `scripts/`, `bin/`, `tools/`, `cli/`
56
+ **Asset directories:** `assets/`, `templates/`, `schemas/`, `configs/`, `examples/`
57
+
58
+ **Script file signals:**
59
+
60
+ | Signal | Strength | Pattern |
61
+ |--------|----------|---------|
62
+ | Entry point declaration | Strong | `package.json` `bin` field, Cargo.toml `[[bin]]`, pyproject.toml `[project.scripts]` |
63
+ | Shebang + executable | Strong | `#!/bin/bash`, `#!/usr/bin/env python`, `#!/usr/bin/env node` |
64
+ | CLI argument parser | Moderate | `argparse`, `yargs`, `commander`, `cobra`, `clap` imports in file |
65
+ | Directory convention | Moderate | File in `scripts/`, `bin/`, `tools/` directory |
66
+ | CI/CD reference | Moderate | Script referenced in `.github/workflows/*.yml` |
67
+
68
+ **Asset file signals:**
69
+
70
+ | Signal | Strength | Pattern |
71
+ |--------|----------|---------|
72
+ | JSON Schema | Strong | `*.schema.json`, file contains `"$schema"` key |
73
+ | Config template | Strong | `*.example`, `*.template.*`, `*.sample` extension |
74
+ | Official example | Moderate | File in `examples/` directory, referenced in README |
75
+ | OpenAPI/GraphQL | Moderate | `openapi.json`, `*.graphql`, `swagger.yaml` |
76
+ | Design tokens | Weak | `tokens.json`, `theme.json` in `assets/` |
77
+
78
+ ### Inclusion Rules
79
+
80
+ - Only include files within brief's `scope.include` patterns (or auto-detected directories)
81
+ - Exclude binary files (check extension: `.so`, `.dll`, `.jar`, `.wasm`, `.exe`)
82
+ - Exclude generated files (`dist/`, `build/`, `.webpack/` output)
83
+ - Exclude vendored/third-party files
84
+ - Flag files >500 lines for user confirmation (may be too large for skill package)
85
+ - If `scripts_intent: "none"` or `assets_intent: "none"` in brief, skip that category
86
+
87
+ ### Provenance and Hashing
88
+
89
+ Each extracted file receives:
90
+ - Citation: `[SRC:{source_path}:L1]` (T1-low — file verified to exist but content not AST-analyzed)
91
+ - Content hash: SHA-256 of file content (for drift detection in audit-skill)
92
+ - Extraction method: `"file-copy"` (distinct from `"ast_bridge"` for code exports)
93
+
94
+ ### Inventory Structure
95
+
96
+ **Script inventory entry:**
97
+ - `name`: filename (e.g., `validate-config.sh`)
98
+ - `source_file`: path relative to source root
99
+ - `purpose`: extracted from file header comments or README reference (if none found, use filename)
100
+ - `language`: detected from extension or shebang
101
+ - `content_hash`: SHA-256
102
+ - `confidence`: T1-low
103
+
104
+ **Asset inventory entry:**
105
+ - `name`: filename (e.g., `config-schema.json`)
106
+ - `source_file`: path relative to source root
107
+ - `purpose`: extracted from file header or schema `title`/`description` field
108
+ - `type`: `template`, `schema`, `config`, `example`
109
+ - `content_hash`: SHA-256
110
+ - `confidence`: T1-low
@@ -28,7 +28,7 @@ Source reading via gh_bridge — infer exports from file structure and content.
28
28
 
29
29
  Structural extraction via ast-grep — verified exports with line-level citations.
30
30
 
31
- > **Note:** `ast_bridge.*` and `qmd_bridge.*` references below are **conceptual interfaces**, not callable functions. They describe the operation to perform. Use ast-grep (MCP tool or CLI) for `ast_bridge.*` operations and QMD (MCP tool or CLI) for `qmd_bridge.*` operations. See the AST Extraction Protocol section below and the TOOL/SUBPROCESS FALLBACK rule for dispatch details.
31
+ > **Note:** `ast_bridge.*`, `qmd_bridge.*`, and `ccc_bridge.*` references below are **conceptual interfaces**, not callable functions. They describe the operation to perform. Use ast-grep (MCP tool or CLI) for `ast_bridge.*` operations, QMD (MCP tool or CLI) for `qmd_bridge.*` operations, and ccc CLI or MCP for `ccc_bridge.*` operations. See the AST Extraction Protocol section below and the TOOL/SUBPROCESS FALLBACK rule for dispatch details.
32
32
 
33
33
  ### Strategy
34
34
 
@@ -52,6 +52,42 @@ Structural extraction via ast-grep — verified exports with line-level citation
52
52
 
53
53
  ---
54
54
 
55
+ ## Forge+ Tier (AST + CCC)
56
+
57
+ Identical extraction to Forge tier. CCC adds an upstream semantic discovery step that pre-ranks the file extraction queue.
58
+
59
+ ### When CCC Pre-Discovery Applies
60
+
61
+ CCC pre-discovery runs in step-02b-ccc-discover (before this extraction step) when ALL of the following are true:
62
+ - Tier is Forge+ or Deep
63
+ - `tools.ccc: true` in forge-tier.yaml
64
+ - `ccc_index.status` is `"fresh"`, `"stale"`, `"created"`, or `"none"`/`"failed"` (step-02b attempts lazy indexing for the latter two)
65
+
66
+ The discovery step stores `{ccc_discovery: [{file, score, snippet}]}` in context. This extraction step consumes those results to pre-rank the file list.
67
+
68
+ ### CCC Pre-Ranking Strategy
69
+
70
+ When `{ccc_discovery}` is present and non-empty:
71
+
72
+ 1. Files appearing in `{ccc_discovery}` results move to the front of the extraction queue, sorted by relevance score descending
73
+ 2. Files NOT in CCC results remain in the queue — they are not excluded, only deprioritized
74
+ 3. If the CCC intersection with scoped files produces <10 files: include all scoped files (CCC results too narrow)
75
+ 4. Proceed with the AST Extraction Protocol on the pre-ranked list
76
+
77
+ ### ast-grep Patterns
78
+
79
+ Same patterns as Forge tier — see Forge tier section above. CCC pre-ranking does not change which AST patterns are used, only which files are processed first.
80
+
81
+ ### Confidence
82
+
83
+ All results: T1 (AST-verified) — identical to Forge tier. CCC is upstream discovery only and is invisible in the output artifact.
84
+
85
+ ### Important
86
+
87
+ CCC pre-discovery failures (ccc unavailable, command error, empty results) always result in standard Forge extraction behavior. This is not reported to the user as a problem — it is normal behavior when ccc has no relevant results for the skill's scope.
88
+
89
+ ---
90
+
55
91
  ## Deep Tier (AST + QMD)
56
92
 
57
93
  Same extraction as Forge tier. Deep tier adds enrichment in step-04, not extraction.
@@ -234,43 +270,9 @@ constraints:
234
270
  regex: '^[A-Z]'
235
271
  ```
236
272
 
237
- ### Re-Export Tracing
238
-
239
- After initial AST extraction, some top-level exports may resolve to **module imports** rather than direct function definitions. This is common in Python libraries that use `__init__.py` re-exports for a clean public API.
240
-
241
- **Detection heuristic:** For each top-level export from `__init__.py` (or equivalent entry point), check if the import path resolves to a directory (contains `__init__.py`) rather than a `.py` file with a matching `def` or `class`. If the initial AST scan found no function/class definition for a known public export, it is likely a module re-export.
242
-
243
- **Tracing protocol:**
244
-
245
- 1. Read the entry point file (e.g., `{package}/__init__.py`) and extract all `from .X import Y` statements
246
- 2. For each import where Y was NOT found by the initial AST scan:
247
- - Check if the import path resolves to a directory (e.g., `{package}/api/v1/delete/` exists with `__init__.py`)
248
- - If directory: read its `__init__.py` to find the actual re-exported symbol
249
- - **Handle aliases:** Check for `from .module import A as B` patterns in the intermediate `__init__.py`. If the parent imports `B`, trace through to `A` in `.module`. If the parent imports `A` but the `__init__.py` only exports it as `B` (via `from .module import A as B`), match by original name `A` and note the alias
250
- - Trace the symbol to its definition file and run AST extraction on that file
251
- 3. Cite the actual definition location: `[AST:{definition_file}:L{line}]`
252
-
253
- **Examples:**
254
-
255
- ```python
256
- # Module re-export — follow required
257
- from .api.v1.delete import delete # delete/ is a directory → read delete/__init__.py
258
-
259
- # Direct function import — no follow needed
260
- from .api.v1.add.add import add # add.py exists with def add()
261
-
262
- # Aliased re-export — follow through alias
263
- # In cognee/api/v1/visualize/__init__.py:
264
- # from .start_visualization_server import visualization_server
265
- # In cognee/__init__.py:
266
- # from .api.v1.visualize import start_visualization_server
267
- # → Match start_visualization_server against both definition names AND alias names
268
- # in the intermediate __init__.py to resolve the chain
269
- ```
270
-
271
- **Unresolvable imports:** If the import statement is a star-import (`from .X import *`) or a conditional import (`try`/`except`), the symbol cannot be reliably traced via this protocol. Record it with `[SRC:{package}/__init__.py:L{line}]` (T1-low) and a note: "star/conditional import — manual trace required."
272
-
273
- **Scope limit:** Only trace re-exports for symbols listed in the top-level entry point's public API. Do not recursively trace beyond one level of `__init__.py` indirection. If a re-export cannot be resolved after one level, record it with a `[SRC:{package}/__init__.py:L{line}]` citation (T1-low) from the import statement itself.
273
+ ### Re-Export Tracing and Script/Asset Extraction
274
274
 
275
- **Other languages:** JS/TS barrel files (`index.ts` with `export { X } from './module'`) follow the same principle — trace the re-export to the definition file. Rust `pub use` and Go package-level re-exports are less common but follow the same heuristic when encountered.
275
+ See `extraction-patterns-tracing.md` for:
276
+ - **Re-export tracing protocol** — resolving module imports through `__init__.py`, barrel files, `pub use`
277
+ - **Script/asset extraction patterns** — detection heuristics, inclusion rules, provenance, inventory structure
276
278
 
@@ -17,8 +17,8 @@ description: >
17
17
 
18
18
  **Frontmatter rules (agentskills.io specification):**
19
19
 
20
- - `name`: 1-64 characters, lowercase alphanumeric + hyphens only, must match parent directory name
21
- - `description`: 1-1024 characters, trigger-optimized for agent matching
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...").
22
22
  - Only 6 fields permitted: `name`, `description`, `license`, `compatibility`, `metadata`, `allowed-tools`
23
23
  - `version` and `author` belong in metadata.json, NOT in frontmatter
24
24
 
@@ -38,6 +38,7 @@ SKILL.md uses a two-tier structure to ensure actionable content survives `split-
38
38
  | 5 | **Key Types** | ~20 lines | Most important enum/type values inline |
39
39
  | 6 | **Architecture at a Glance** | ~10 lines | Bullet list of subsystem categories |
40
40
  | 7 | **CLI** | ~10 lines | Basic CLI commands (skip if no CLI) |
41
+ | 7b | **Scripts & Assets** | ~10 lines | Manifest of included scripts and assets (skip if none detected) |
41
42
  | 8 | **Manual Sections** | ~5 lines | `<!-- [MANUAL] -->` markers for update-skill |
42
43
 
43
44
  #### Tier 2 — Reference-Eligible (extracted by split-body into references/)
@@ -55,7 +56,8 @@ SKILL.md uses a two-tier structure to ensure actionable content survives `split-
55
56
  - Tier 1 sections are kept short enough that `split-body` targets the larger Tier 2 sections (`## Full` headings) into `references/`
56
57
  - After split-body, SKILL.md retains all Tier 1 content — actionable without loading references
57
58
  - An agent loading only SKILL.md (no references) must get enough to act
58
- - **Section 4b (Migration & Deprecation Warnings)** is conditional: only emitted for Deep tier when T2-future annotations exist. Quick/Forge tiers and Deep tiers without T2-future annotations omit it entirely (no empty section). Parsers and validators must treat this section as optional.
59
+ - **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
+ - **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.
59
61
 
60
62
  ### Provenance Citation Format
61
63
 
@@ -118,9 +120,12 @@ Indexed pipe-delimited format for CLAUDE.md managed section (~80-120 tokens per
118
120
  "source_repo": "{github-url}",
119
121
  "source_root": "{resolved-source-path}",
120
122
  "source_commit": "{commit-hash}",
121
- "confidence_tier": "{Quick|Forge|Deep}",
123
+ "confidence_tier": "{Quick|Forge|Forge+|Deep}",
122
124
  "spec_version": "1.3",
123
125
  "generation_date": "{ISO-8601}",
126
+ "description": "{SKILL.md frontmatter description}",
127
+ "language": "{primary-source-language}",
128
+ "ast_node_count": "{number-or-omitted-if-no-ast}",
124
129
  "exports": [],
125
130
  "tool_versions": {
126
131
  "ast_grep": "{version-or-null}",
@@ -136,8 +141,16 @@ Indexed pipe-delimited format for CLAUDE.md managed section (~80-120 tokens per
136
141
  "total_coverage": 0.0,
137
142
  "confidence_t1": 0,
138
143
  "confidence_t2": 0,
139
- "confidence_t3": 0
144
+ "confidence_t3": 0,
145
+ "scripts_count": 0,
146
+ "assets_count": 0
140
147
  },
148
+ "scripts": [
149
+ { "file": "scripts/{name}", "purpose": "{description}", "source_file": "{source-path}", "confidence": "T1-low" }
150
+ ],
151
+ "assets": [
152
+ { "file": "assets/{name}", "purpose": "{description}", "source_file": "{source-path}", "confidence": "T1-low" }
153
+ ],
141
154
  "dependencies": [],
142
155
  "compatibility": "{semver-range}"
143
156
  }
@@ -163,6 +176,7 @@ Each reference file includes:
163
176
  - Complete usage examples
164
177
  - Related functions cross-references
165
178
  - Temporal annotations (Deep tier: T2-past, T2-future)
179
+ - **Table of contents** (required for files exceeding 100 lines) — a `## Contents` section at the top listing all sub-sections for agent discoverability
166
180
 
167
181
  ---
168
182
 
@@ -186,10 +200,22 @@ Each reference file includes:
186
200
  "extraction_method": "ast_bridge.scan_definitions",
187
201
  "ast_node_type": "export_function_declaration"
188
202
  }
203
+ ],
204
+ "file_entries": [
205
+ {
206
+ "file_name": "scripts/{name}",
207
+ "file_type": "script",
208
+ "source_file": "{source-path}",
209
+ "confidence": "T1-low",
210
+ "extraction_method": "file-copy",
211
+ "content_hash": "sha256:{hash}"
212
+ }
189
213
  ]
190
214
  }
191
215
  ```
192
216
 
217
+ `scripts` and `assets` arrays in metadata.json are optional — omit entirely (not empty arrays) when no scripts/assets exist. `file_entries` in provenance-map.json is optional — omit when no scripts/assets exist.
218
+
193
219
  ---
194
220
 
195
221
  ## evidence-report.md Structure