Testing Handbook Generator
Trail of BitsOfficialPublished by Trail of Bits
- Skill
- Workflow
- Agent tooling
- CC-BY-SA-4.0
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
The testing-handbook-generator is a workflow-based skill designed to transform content from the Trail of Bits Testing Handbook into structured Claude Code skills. It follows a multi-phase process that includes handbook discovery, planning, two-pass content generation, and validation. The skill ensures that generated documentation adheres to specific templates based on the handbook section type, such as tools, fuzzers, techniques, or domains. It also manages cross-references between generated skills and updates repository documentation to maintain consistency.
What it does
- Analyzes the Trail of Bits Testing Handbook to identify potential skills.
- Generates structured SKILL.md files using predefined templates.
- Executes a two-pass generation process to handle cross-references between skills.
- Validates generated skills and their cross-references using automated scripts.
- Updates the repository README and cross-reference graphs.
- Supports regeneration of individual skills from specific handbook sections.
When to use it
- When you need to create new security testing skills derived from the appsec.guide handbook.
- When you need to refresh existing skills based on updates to the handbook content.
- When you are performing bulk skill generation or maintenance within the plugin structure.
- When a user explicitly references the testing handbook or appsec.guide.
Advantages
- Ensures consistent structure across all generated security skills.
- Automates the complex task of managing inter-skill dependencies.
- Provides a clear workflow for validating and integrating new skills into the repository.
- Reduces manual effort in maintaining documentation and cross-references.
Usage examples
- “Generate skills from the testing handbook”
- The agent initiates the discovery phase, scans the handbook, presents a generation plan for approval, and proceeds to create the skills.
- “Create a skill for the libFuzzer section”
- The agent reads the specific libFuzzer handbook section, applies the fuzzer-skill template, and generates the corresponding SKILL.md file.
- “Regenerate the semgrep skill from the handbook”
- The agent re-reads the relevant handbook section, overwrites the existing semgrep SKILL.md, and updates cross-references.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/trailofbits/testing-handbook-generator/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip testing-handbook-generator.zip -d .agents/skills
Documentation by Trail of Bits
Testing Handbook Skill Generator
Generate and maintain Claude Code skills from the Trail of Bits Testing Handbook.
When to Use
Invoke this skill when:
Creating new security testing skills from handbook content
User mentions "testing handbook", "appsec.guide", or asks about generating skills
Bulk skill generation or refresh is needed
Do NOT use for:
General security testing questions (use the generated skills)
Non-handbook skill creation
Handbook Location
The skill needs the Testing Handbook repository. See discovery.md for full details.
Quick reference: Check ./testing-handbook, ../testing-handbook, ~/testing-handbook → ask user → clone as last resort.
Repository: https://github.com/trailofbits/testing-handbook
Workflow Overview
Phase 0: Setup Phase 1: Discovery
┌─────────────────┐ ┌─────────────────┐
│ Locate handbook │ → │ Analyze handbook│
│ - Find or clone │ │ - Scan sections │
│ - Confirm path │ │ - Classify types│
└─────────────────┘ └─────────────────┘
↓ ↓
Phase 3: Generation Phase 2: Planning
┌─────────────────┐ ┌─────────────────┐
│ TWO-PASS GEN │ ← │ Generate plan │
│ Pass 1: Content │ │ - New skills │
│ Pass 2: X-refs │ │ - Updates │
│ - Write to gen/ │ │ - Present user │
└─────────────────┘ └─────────────────┘
↓
Phase 4: Testing Phase 5: Finalize
┌─────────────────┐ ┌─────────────────┐
│ Validate skills │ → │ Post-generation │
│ - Run validator │ │ - Update README │
│ - Test activation│ │ - Update X-refs │
│ - Fix issues │ │ - Self-improve │
└─────────────────┘ └─────────────────┘Scope Restrictions
ONLY modify these locations:
plugins/testing-handbook-skills/skills/[skill-name]/*- Generated skills (as siblings to testing-handbook-generator)plugins/testing-handbook-skills/skills/testing-handbook-generator/*- Self-improvementRepository root
README.md- Add generated skills to table
NEVER modify or analyze:
Other plugins (
plugins/property-based-testing/,plugins/static-analysis/, etc.)Other skills outside this plugin
Do not scan or pull into context any skills outside of testing-handbook-skills/. Generate skills based solely on handbook content and resources referenced from it.
Quick Reference
Section → Skill Type Mapping
| Handbook Section | Skill Type | Template |
|---|---|---|
/static-analysis/[tool]/ | Tool Skill | tool-skill.md |
/fuzzing/[lang]/[fuzzer]/ | Fuzzer Skill | fuzzer-skill.md |
/fuzzing/techniques/ | Technique Skill | technique-skill.md |
/crypto/[tool]/ | Domain Skill | domain-skill.md |
/web/[tool]/ | Tool Skill | tool-skill.md |
Skill Candidate Signals
| Signal | Indicates |
|---|---|
_index.md with bookCollapseSection: true | Major tool/topic |
| Numbered files (00-, 10-, 20-) | Structured content |
techniques/ subsection | Methodology content |
99-resources.md or 91-resources.md | Has external links |
Exclusion Signals
| Signal | Action |
|---|---|
draft: true in frontmatter | Skip section |
| Empty directory | Skip section |
| Template/placeholder file | Skip section |
GUI-only tool (e.g., web/burp/) | Skip section (Claude cannot operate GUI tools) |
Decision Tree
Starting skill generation?
├─ Need to analyze handbook and build plan?
│ └─ Read: discovery.md
│ (Handbook analysis methodology, plan format)
│
├─ Spawning skill generation agents?
│ └─ Read: agent-prompt.md
│ (Full prompt template, variable reference, validation checklist)
│
├─ Generating a specific skill type?
│ └─ Read appropriate template:
│ ├─ Tool (Semgrep, CodeQL) → templates/tool-skill.md
│ ├─ Fuzzer (libFuzzer, AFL++) → templates/fuzzer-skill.md
│ ├─ Technique (harness, coverage) → templates/technique-skill.md
│ └─ Domain (crypto, web) → templates/domain-skill.md
│
├─ Validating generated skills?
│ └─ Run: scripts/validate-skills.py
│ Then read: testing.md for activation testing
│
├─ Finalizing after generation?
│ └─ See: Post-Generation Tasks below
│ (Update main README, update Skills Cross-Reference, self-improvement)
│
└─ Quick generation from specific section?
└─ Use Quick Reference above, apply template directlyTwo-Pass Generation (Phase 3)
Generation uses a two-pass approach to solve forward reference problems (skills referencing other skills that don't exist yet).
Pass 1: Content Generation (Parallel)
Generate all skills in parallel without the Related Skills section:
Pass 1 - Generating 5 skills in parallel:
├─ Agent 1: libfuzzer (fuzzer) → skills/libfuzzer/SKILL.md
├─ Agent 2: aflpp (fuzzer) → skills/aflpp/SKILL.md
├─ Agent 3: semgrep (tool) → skills/semgrep/SKILL.md
├─ Agent 4: harness-writing (technique) → skills/harness-writing/SKILL.md
└─ Agent 5: wycheproof (domain) → skills/wycheproof/SKILL.md
Each agent uses: pass=1 (content only, Related Skills left empty)Pass 1 agents:
Generate all sections EXCEPT Related Skills
Leave a placeholder:
## Related Skills\n\n<!-- PASS2: populate after all skills exist -->Output report includes
references: DEFERRED
Pass 2: Cross-Reference Population (Sequential)
After all Pass 1 agents complete, run Pass 2 to populate Related Skills:
Pass 2 - Populating cross-references:
├─ Read all generated skill names from skills/*/SKILL.md
├─ For each skill, determine related skills based on:
│ ├─ related_sections from discovery (handbook structure)
│ ├─ Skill type relationships (fuzzers → techniques)
│ └─ Explicit mentions in content
└─ Update each SKILL.md's Related Skills sectionPass 2 process:
Collect all generated skill names:
ls -d skills/*/SKILL.mdFor each skill, identify related skills using the mapping from discovery
Edit each SKILL.md to replace the placeholder with actual links
Validate cross-references exist (no broken links)
Agent Prompt Template
See agent-prompt.md for the full prompt template with:
Variable substitution reference (including
passvariable)Pre-write validation checklist
Hugo shortcode conversion rules
Line count splitting rules
Error handling guidance
Output report format
Collecting Results
After Pass 1: Aggregate output reports, verify all skills generated. After Pass 2: Run validator to check cross-references.
Handling Agent Failures
If an agent fails or produces invalid output:
| Failure Type | Detection | Recovery Action |
|---|---|---|
| Agent crashed | No output report | Re-run single agent with same inputs |
| Validation failed | Output report shows errors | Check gaps/warnings, manually patch or re-run |
| Wrong skill type | Content doesn't match template | Re-run with corrected type parameter |
| Missing content | Output report lists gaps | Accept if minor, or provide additional related_sections |
| Pass 2 broken ref | Validator shows missing skill | Check if skill was skipped, update reference |
Important: Do NOT re-run the entire parallel batch for a single agent failure. Fix individual failures independently.
Single-Skill Regeneration
To regenerate a single skill without re-running the entire batch:
# Regenerate single skill (Pass 1 - content only)
"Use testing-handbook-generator to regenerate the {skill-name} skill from section {section_path}"
# Example:
"Use testing-handbook-generator to regenerate the libfuzzer skill from section fuzzing/c-cpp/10-libfuzzer"Regeneration workflow:
Re-read the handbook section for fresh content
Apply the appropriate template
Write to
skills/{skill-name}/SKILL.md(overwrites existing)Re-run Pass 2 for that skill only to update cross-references
Run validator on the single skill:
uv run scripts/validate-skills.py --skill {skill-name}
Output Location
Generated skills are written to:
skills/[skill-name]/SKILL.mdEach skill gets its own directory for potential supporting files (as siblings to testing-handbook-generator).
Quality Checklist
Before delivering generated skills:
[ ] All handbook sections analyzed (Phase 1)
[ ] Plan presented to user before generation (Phase 2)
[ ] Parallel agents launched - one per skill (Phase 3)
[ ] Templates applied correctly per skill type
[ ] Validator passes:
uv run scripts/validate-skills.py[ ] Activation testing passed - see testing.md
[ ] Main
README.mdupdated with generated skills table[ ]
README.mdSkills Cross-Reference graph updated[ ] Self-improvement notes captured
[ ] User notified with summary
Post-Generation Tasks
1. Update Main README
After generating skills, update the repository's main README.md to list them.
Format: Add generated skills to the same "Available Plugins" table, directly after testing-handbook-skills. Use plain text testing-handbook-generator as the author (no link).
Example:
| Plugin | Description | Author |
|--------|-------------|--------|
| ... other plugins ... |
| [testing-handbook-skills](plugins/testing-handbook-skills/) | Meta-skill that generates skills from the Testing Handbook | Paweł Płatek |
| [libfuzzer](plugins/testing-handbook-skills/skills/libfuzzer/) | Coverage-guided fuzzing with libFuzzer for C/C++ | testing-handbook-generator |
| [aflpp](plugins/testing-handbook-skills/skills/aflpp/) | Multi-core fuzzing with AFL++ | testing-handbook-generator |
| [semgrep](plugins/testing-handbook-skills/skills/semgrep/) | Fast static analysis for finding bugs | testing-handbook-generator |2. Update Skills Cross-Reference
After generating skills, update the README.md's Skills Cross-Reference section with the mermaid graph showing skill relationships.
Process:
Read each generated skill's
SKILL.mdand extract its## Related SkillssectionBuild the mermaid graph with nodes grouped by skill type (Fuzzers, Techniques, Tools, Domain)
Add edges based on the Related Skills relationships:
Solid arrows (
-->) for primary technique dependenciesDashed arrows (
-.->) for alternative tool suggestions
Replace the existing mermaid code block in README.md
Edge classification:
| Relationship | Arrow Style | Example |
|---|---|---|
| Fuzzer → Technique | --> | libfuzzer --> harness-writing |
| Tool → Tool (alternative) | -.-> | semgrep -.-> codeql |
| Fuzzer → Fuzzer (alternative) | -.-> | libfuzzer -.-> aflpp |
| Technique → Technique | --> | harness-writing --> coverage-analysis |
Validation: After updating, run validate-skills.py to verify all referenced skills exist.
3. Self-Improvement
After each generation run, reflect on what could improve future runs.
Capture improvements to:
Templates (missing sections, better structure)
Discovery logic (missed patterns, false positives)
Content extraction (shortcodes not handled, formatting issues)
Update process:
Note issues encountered during generation
Identify patterns that caused problems
Update relevant files:
SKILL.md- Workflow, decision tree, quick reference updatestemplates/*.md- Template improvementsdiscovery.md- Detection logic updatestesting.md- New validation checks
Document the improvement in commit message
Example self-improvement:
Issue: libFuzzer skill missing sanitizer flags table
Fix: Updated templates/fuzzer-skill.md to include ## Compiler Flags sectionExample Usage
Full Discovery and Generation
User: "Generate skills from the testing handbook"
1. Locate handbook (check common locations, ask user, or clone)
2. Read discovery.md for methodology
3. Scan handbook at {handbook_path}/content/docs/
4. Build candidate list with types
5. Present plan to user
6. On approval, generate each skill using appropriate template
7. Validate generated skills
8. Update main README.md with generated skills table
9. Update README.md Skills Cross-Reference graph from Related Skills sections
10. Self-improve: note any template/discovery issues for future runs
11. Report resultsSingle Section Generation
User: "Create a skill for the libFuzzer section"
1. Read /testing-handbook/content/docs/fuzzing/c-cpp/10-libfuzzer/
2. Identify type: Fuzzer Skill
3. Read templates/fuzzer-skill.md
4. Extract content, apply template
5. Write to skills/libfuzzer/SKILL.md
6. Validate and reportTips
Do:
Always present plan before generating
Use appropriate template for skill type
Preserve code blocks exactly
Validate after generation
Don't:
Generate without user approval
Skip fetching non-video external resources (use WebFetch)
Fetch video URLs (YouTube, Vimeo - titles only)
Include handbook images directly
Skip validation step
Exceed 500 lines per SKILL.md
For first-time use: Start with discovery.md to understand the handbook analysis process.
For template reference: See templates/ directory for skill type templates.
For validation: See testing.md for quality assurance methodology.
Files
- ATTRIBUTION.mdAdded by AutoGineer969 B
- LICENSELicence file added by AutoGineer19.7 KiB
- SKILL.md14.3 KiB
- agent-prompt.md11.2 KiB
- agents/openai.yaml256 B
- assets/trail-of-bits-mark.svg3.0 KiB
- discovery.md15.4 KiB
- templates/domain-skill.md16.6 KiB
- templates/fuzzer-skill.md11.1 KiB
- templates/technique-skill.md12.3 KiB
- templates/tool-skill.md9.2 KiB
- testing.md16.3 KiB
discovery.md
Discovery Workflow
Methodology for analyzing the Testing Handbook and identifying skill candidates.
Quick Navigation:
Phase 0: Locate Handbook
Phase 1: Handbook Analysis
Phase 2: Plan Generation
Phase 3: Prepare Generation Context
Progress Tracking
Use TodoWrite throughout discovery to track progress and give visibility to the user:
Discovery phase todos:
- [ ] Locate handbook repository
- [ ] Scan /fuzzing/ sections
- [ ] Scan /static-analysis/ sections
- [ ] Scan /crypto/ sections
- [ ] Scan /web/ sections
- [ ] Build candidate list with types
- [ ] Resolve conflicts and edge cases
- [ ] Present plan to user
- [ ] Await user approvalMark each todo as in_progress when starting and completed when done. This helps users understand where you are in the process.
Phase 0: Locate Handbook
Before analysis, locate or obtain the Testing Handbook repository.
Step 1: Check Common Locations
# Check common locations (simple version)
for dir in ./testing-handbook ../testing-handbook ~/testing-handbook; do
[ -d "$dir/content/docs" ] && handbook_path="$dir" && echo "✓ Found: $dir" && break
done
[ -z "$handbook_path" ] && echo "Handbook not found in common locations"Step 2: Ask User (if not found)
If handbook not found in common locations:
"Where is the Testing Handbook repository located? (full path)"
Step 3: Clone as Last Resort (if user agrees)
git clone --depth=1 https://github.com/trailofbits/testing-handbook.git
handbook_path="./testing-handbook"Set handbook_path Variable
Once located, set handbook_path and use it for all subsequent paths:
handbook_path="/path/to/testing-handbook" # Set to actual locationAll paths below are relative to {handbook_path}.
Error Recovery
| Failure | Detection | Recovery |
|---|---|---|
| Handbook not in common locations | Step 1 finds nothing | Ask user for path (Step 2) |
| User doesn't know path | User says "I don't know" | Offer to clone (Step 3) |
| Clone fails (network/permissions) | git clone returns error | Report error, ask user to clone manually and provide path |
content/docs/ missing | Directory doesn't exist after locating | Invalid handbook - ask user to verify it's the correct repo |
| Handbook is outdated | User mentions old content | Suggest git pull in handbook directory |
Phase 1: Handbook Analysis
1.1 Scan Directory Structure
Scan the handbook at:
{handbook_path}/content/docs/Directory structure pattern:
docs/
├── fuzzing/
│ ├── _index.md # Section overview
│ ├── c-cpp/
│ │ ├── _index.md # Language subsection
│ │ ├── 10-libfuzzer/ # Tool directory
│ │ │ └── index.md
│ │ ├── 11-aflpp/
│ │ └── techniques/ # Shared techniques
│ └── rust/
├── static-analysis/
│ ├── semgrep/
│ │ ├── _index.md
│ │ ├── 00-installation.md
│ │ ├── 10-advanced.md
│ │ ├── 20-ci.md
│ │ └── 99-resources.md
│ └── codeql/
├── crypto/
│ ├── wycheproof/
│ └── constant_time_tool/
└── web/
└── burp/1.2 Parse Frontmatter
Each markdown file has YAML frontmatter:
---
title: "Semgrep"
weight: 2
summary: "Fast static analysis for finding bugs..."
bookCollapseSection: true
draft: false # Check this!
---Key fields:
| Field | Purpose |
|---|---|
title | Skill name candidate |
summary | Skill description source |
weight | Ordering (lower = more important) |
bookCollapseSection | Indicates major section |
draft | If true, skip this section |
1.3 Identify Skill Candidates
Decision Table:
For each directory found, apply the first matching rule:
| Directory Pattern | Has | Skill Type | Action |
|---|---|---|---|
_index.md with bookCollapseSection: true | - | Container | Scan children, don't create skill for container itself |
**/static-analysis/[name]/ | Numbered files (00-, 10-) | Tool | Create tool skill |
**/fuzzing/[lang]/[name]/ | index.md or numbered files | Fuzzer | Create fuzzer skill |
**/fuzzing/techniques/[name]/ | Any .md files | Technique | Create technique skill |
**/crypto/[name]/ | Any .md files | Domain | Create domain skill |
**/web/[name]/ | Numbered files or _index.md | Tool | Create tool skill (but check exclusions) |
Named techniques/ | Subdirectories | Container | Create one technique skill per subdirectory |
| Any other | Only _index.md | Skip | Not enough content |
Hard Exclusions (GUI-only tools):
Some handbook sections describe tools that require graphical user interfaces and cannot be operated by Claude. Skip these unconditionally:
| Section | Tool | Reason |
|---|---|---|
**/web/burp/ | Burp Suite | GUI-based HTTP proxy; requires visual interaction |
These tools are excluded because Claude cannot:
Launch or interact with GUI applications
Click buttons, navigate menus, or view visual elements
Operate browser-based or desktop UI tools
For web security testing, prefer CLI-based alternatives documented elsewhere (e.g., curl, httpie, custom scripts).
Classification priority (when multiple patterns match):
Most specific path wins (deeper = higher priority)
Type preference: Tool > Fuzzer > Technique > Domain
When in doubt, flag for user review in the plan
Examples:
| Path | Matches | Result |
|---|---|---|
/fuzzing/c-cpp/10-libfuzzer/ | Fuzzer pattern | libfuzzer (fuzzer) |
/static-analysis/semgrep/ | Tool pattern | semgrep (tool) |
/fuzzing/techniques/writing-harnesses/ | Technique pattern | harness-writing (technique) |
/crypto/wycheproof/ | Domain pattern | wycheproof (domain) |
1.4 Build Candidate List
For each candidate, extract:
- name: libfuzzer
type: fuzzer
source: /docs/fuzzing/c-cpp/10-libfuzzer/
summary: "libFuzzer is a coverage-guided fuzzer..."
weight: 1
has_resources: true # Has 99-resources.md
related_sections:
- /docs/fuzzing/techniques/01-writing-harnesses/
- /docs/fuzzing/techniques/03-asan/1.5 Candidate Prioritization
When many candidates exist, prioritize by:
| Priority | Criterion | Rationale |
|---|---|---|
| 1 | Weight field (lower = higher) | Handbook author's intent |
| 2 | Content depth (more numbered files) | More complete documentation |
| 3 | Has resources file | External links add value |
| 4 | Core section (fuzzing, static-analysis) | Fundamental topics |
| 5 | Recently updated | More relevant content |
Conflict resolution:
If multiple patterns match a section, use the most specific (deepest path wins)
If a section could be multiple types, prefer: Tool > Fuzzer > Technique > Domain
When in doubt, flag for user review in the plan
Phase 2: Plan Generation
2.1 Plan Format
Present to user in this format:
# Skill Generation Plan
## Summary
- **Handbook analyzed:** {handbook_path}
- **Total sections:** 25
- **Skills to generate:** 8
- **Sections to skip:** 2
---
## Skills to Generate
| # | Skill Name | Source Section | Type | Related Sections |
|---|------------|----------------|------|------------------|
| 1 | libfuzzer | /fuzzing/c-cpp/10-libfuzzer/ | Fuzzer | techniques/asan, techniques/harness |
| 2 | aflpp | /fuzzing/c-cpp/11-aflpp/ | Fuzzer | techniques/asan |
| 3 | cargo-fuzz | /fuzzing/rust/10-cargo-fuzz/ | Fuzzer | - |
| 4 | wycheproof | /crypto/wycheproof/ | Domain | - |
| 5 | fuzz-harness-writing | /fuzzing/techniques/01-writing-harnesses/ | Technique | - |
| 6 | coverage-analysis | /fuzzing/c-cpp/techniques/01-coverage/ | Technique | - |
| 7 | address-sanitizer | /fuzzing/techniques/03-asan/ | Technique | - |
---
## Skipped Sections
| Section | Reason |
|---------|--------|
| /docs/dynamic-analysis/ | `draft: true` in frontmatter |
| /docs/fuzzing/3-python.md | Single file, insufficient content |
| /docs/web/burp/ | GUI-only tool (excluded) |
---
## External Resources to Fetch
| Section | Resource Count | Source File |
|---------|---------------|-------------|
| Fuzzing | 5 | /fuzzing/91-resources.md |
| Semgrep | 3 | /static-analysis/semgrep/99-resources.md |
| CodeQL | 4 | /static-analysis/codeql/99-resources.md |
---
## Actions
- [ ] Confirm plan and proceed with generation
- [ ] Modify: Remove skill #X from plan
- [ ] Modify: Change skill #Y type
- [ ] Cancel generationMake the actions navigable and selectable if possible using built-in tool like TodoWrite.
2.2 User Interaction
After presenting plan:
Wait for user confirmation or modifications
Apply any modifications to plan
Proceed with generation only after explicit approval
Acceptable modifications:
Remove skills from plan
Change skill type
Skip updates
Add custom related sections
Change skill names
Phase 3: Prepare Generation Context
This phase prepares everything needed for generation agents. It combines content aggregation with agent handoff preparation.
3.1 Collect Content Per Skill
For each approved skill, collect content from:
Primary section: Main
_index.mdorindex.mdNumbered files:
00-installation.md,10-advanced.md, etc.Related sections: As specified in
related_sectionsResources: From
99-resources.md(titles only)
3.2 Content Processing Rules
Content processing rules are defined in the agent prompt template.
Authoritative source: agent-prompt.md
The agent prompt contains:
Hugo shortcode conversion table
Code block preservation rules
Image/video handling
YAML frontmatter requirements
Pre-write validation checklist
Line count splitting rules (when to split large skills)
Do not duplicate these rules here. Generation agents receive them via the prompt template.
3.3 External Resources
Extract from 99-resources.md or 91-resources.md:
## Resources
- [Introduction to Semgrep](https://www.youtube.com/watch?v=...) - Trail of Bits Webinar
- [Semgrep Documentation](https://semgrep.dev/docs/) - Official docs
- [Custom Rules Guide](https://semgrep.dev/docs/writing-rules/) - Rule authoringFor non-video resources (documentation, blogs, guides):
Use WebFetch to retrieve content
Extract key insights, techniques, code examples
Summarize actionable information for the skill
Include attribution with URL
For video resources (YouTube, Vimeo, etc.):
Extract title and URL only
Do NOT attempt to fetch video content
Include brief description if available in handbook
Video URL patterns to skip fetching:
youtube.com,youtu.bevimeo.com*.mp4,*.webm,*.movdirect linkstwitch.tv,dailymotion.com
3.4 Edge Case Handling
| Situation | Detection | Action |
|---|---|---|
| Empty handbook section | Directory exists but no .md files | Skip, add to "Skipped Sections" with reason |
| Draft content | draft: true in frontmatter | Skip entirely, do not include in plan |
Missing _index.md | Directory has content but no index | Use first numbered file for metadata |
| Conflicting frontmatter | Different titles in _index.md vs content | Use _index.md values, note discrepancy |
| Missing resources file | No 99-resources.md or 91-resources.md | Omit Resources section from generated skill |
| Circular references | Section A references B, B references A | Include each once, note relationship |
| Very large section | >20 markdown files | Flag for splitting (see agent-prompt.md) |
| Incomplete section | TODO or placeholder text | Flag in plan for user decision |
3.5 Build Per-Skill Package
Each skill generation agent receives variables that map directly to the agent prompt template:
# Agent prompt variables (see agent-prompt.md for full template)
name: "libfuzzer" # {name} - skill name (lowercase)
type: "fuzzer" # {type} - tool|fuzzer|technique|domain
pass: 1 # {pass} - 1=content only, 2=cross-refs only
handbook_path: "/path/to/testing-handbook" # {handbook_path} - absolute path
section_path: "fuzzing/c-cpp/10-libfuzzer" # {section_path} - relative to content/docs/
output_dir: "/path/to/skills/plugins/testing-handbook-skills/skills" # {output_dir}
template_path: "skills/testing-handbook-generator/templates/fuzzer-skill.md" # {template_path}
related_sections: "fuzzing/techniques/01-writing-harnesses, fuzzing/techniques/03-asan"
# ^ Use comma-separated list OR empty string "" if no related sections
# Metadata (for orchestrator tracking, not passed to agent)
metadata:
title: "libFuzzer" # From frontmatter
summary: "Coverage-guided fuzzer..." # From frontmatter
has_resources: true # Has 99-resources.md
estimated_lines: 350 # Approximate output sizeVariable mapping to agent prompt:
| Package Field | Agent Prompt Variable | Example |
|---|---|---|
name | {name} | libfuzzer |
type | {type} | fuzzer |
pass | {pass} | 1 or 2 |
handbook_path | {handbook_path} | /path/to/testing-handbook |
section_path | {section_path} | fuzzing/c-cpp/10-libfuzzer |
output_dir | {output_dir} | /path/to/skills/plugins/testing-handbook-skills/skills |
template_path | {template_path} | skills/testing-handbook-generator/templates/fuzzer-skill.md |
related_sections | {related_sections} | Comma-separated list or empty string |
Building the package:
# Construct output_dir from current location
output_dir="$(cd .. && pwd)" # Parent of testing-handbook-generator
# Construct template_path from type
template_path="skills/testing-handbook-generator/templates/${type}-skill.md"
# Format related sections (empty string if none)
if [ ${#related_sections[@]} -eq 0 ]; then
related_sections=""
else
related_sections=$(IFS=', '; echo "${related_sections[*]}")
fi3.6 Pre-Generation Validation
Before launching generation agents, verify:
For each skill candidate:
├─ Primary content exists and is non-empty
├─ Frontmatter has title and summary
├─ At least one code block present (for tool/fuzzer types)
├─ No unresolved Hugo shortcodes in source content
├─ Related sections (if any) are accessible
└─ Template file exists for skill typeIf validation fails:
Log the specific failure
Move candidate to "Skipped Sections" with reason
Continue with remaining candidates
3.7 Launch Generation
Trigger conditions:
User has approved plan (explicit confirmation)
All source paths verified accessible
All per-skill packages prepared
Launch sequence:
Launch Pass 1 agents in parallel (content generation)
Wait for all Pass 1 agents to complete
Run Pass 2 (cross-reference population) - see SKILL.md
Run validator on all generated skills
3.8 Success Criteria
Phase 3 complete when:
[ ] All skill packages prepared with variables
[ ] Pass 1 agents launched and completed
[ ] Pass 2 cross-references populated
[ ] All generated skills pass validation
Requirements and compatibility
Written for: Claude Code
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Names Claude Code tools, Needs Python
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Published by
- Trail of Bits
- Publisher
- Trail of Bits (Official)
- Source
- trailofbits/skills · plugins/testing-handbook-skills/skills/testing-handbook-generator · commit e4dd0bb
- Licence
- Creative Commons Attribution-ShareAlike 4.0 International (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Trail of Bits or Trail of Bits.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download testing-handbook-generator.zip