# Skill Development Workflow

> Implements the complete skill creation lifecycle from research through validation, including Python-based quality gates, stub detection, and automated compliance checking against SKILL_FORMAT_SPEC.md requirements.

- Skill: `paulpas/skill-development-workflow` (Agent Skill)
- Install (CLI): `npx skillmds@latest add paulpas/skill-development-workflow`
- Raw SKILL.md: https://api.skillmd.com/api/skills/paulpas/skill-development-workflow/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Research & Search
- License: MIT
- Author: paulpas (https://skillmd.com/u/paulpas)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/paulpas/skill-development-workflow

---





# Skill Development Workflow

Implements the complete skill creation lifecycle with automated quality gates to ensure every SKILL.md meets repository standards before commit. This skill provides Python-based validators that check file size, stub sentinels, code block counts, trigger diversity, and domain-specific structural requirements.

## TL;DR Checklist

- [ ] Run `validate_skill.sh` — must exit 0 (PASS)
- [ ] File is ≥ 3,000 bytes of content (excluding frontmatter)
- [ ] No stub sentinel: "IMPLEMENTING THIS SPECIFIC PATTERN OR FEATURE"
- [ ] At least 2 fenced code blocks for implementation skills
- [ ] Core Workflow uses domain-specific steps with checkpoints — no generic patterns
- [ ] `metadata.triggers` has 5–8 specific terms with both technical and conversational variants
- [ ] H1 title is human-readable, not the kebab-case name
- [ ] Description leads with an active verb and includes 1–2 domain-specific terms

---

## When to Use

Use this skill when:

- Creating a new SKILL.md file for any domain (agent, cncf, coding, go, linux, trading, programming, writing)
- Auditing an existing SKILL.md before committing to the repository
- Fixing validation failures reported by `scripts/validate_skill.sh`
- Migrating skills from another format into the OpenCode skill system
- Setting up CI/CD checks for automated skill quality gates in a pipeline

---

## When NOT to Use

Avoid this skill for:

- Reviewing source code logic or algorithm correctness — use `coding-code-review` instead
- Designing trigger keywords for auto-loading — use `agent-skill-trigger-engineering` instead
- Content editing of documentation outside the SKILL.md format — use domain-specific writing skills

---

## Core Workflow

1. **Research and Scope the Domain** — Study 3–5 existing skills in the target domain to understand conventions, code patterns, and structural norms. Check `skills/<domain>/` for similar topics to avoid duplication.
   **Checkpoint:** Verify no existing skill covers the same topic by comparing descriptions against `python3 scripts/generate_readme.py --list`.

2. **Draft Frontmatter** — Create YAML frontmatter with: exact kebab-case name matching the directory, active-verb description under 200 characters, domain-specific triggers (5–8 terms), and appropriate role/scope/output-format from the domain defaults table in SKILL_FORMAT_SPEC.md.
   **Checkpoint:** `name` field must exactly match the directory name. `metadata.domain` must match the parent directory.

3. **Write H1 Title and Role Paragraph** — Title must be human-readable (e.g., "Stop Loss Manager", not "risk-stop-loss"). The role paragraph (1–3 sentences) describes what the model does when this skill loads, written from the model's perspective.
   **Checkpoint:** No abstract descriptions like "This skill is for X." Use active voice: "Implements…", "Analyzes…", "Selects…".

4. **Implement Core Workflow with Domain-Specific Steps** — Number each step. Include a **Checkpoint** after steps requiring verification. Each step must contain specific actions, commands, file paths, or formulas — not generic instructions like "Identify the use case" or "Apply the pattern."
   **Checkpoint:** Read each step aloud. If it could apply to any domain without modification, rewrite it with domain-specific detail.

5. **Add Implementation Patterns or Reference Guide** — For implementation skills: include at least 2 real code blocks with typed signatures and docstrings. For reference skills: include complete working examples (YAML manifests, PromQL queries, shell scripts). Include at least one BAD vs. GOOD comparison pair.
   **Checkpoint:** Every code block must contain real, working code — no `pass` bodies, no `return {}`, no "your code here" placeholders.

6. **Write Constraints (MUST DO / MUST NOT DO)** — Each constraint must be a short imperative sentence that is actionable and specific. Avoid generic phrases like "follow best practices." Instead: "Base trailing stop distance on ATR, not a fixed price or percentage."
   **Checkpoint:** Remove any constraint that doesn't contain a concrete, testable rule.

7. **Add When NOT to Use** — List 2–4 situations where this skill creates overhead without benefit. Reference related skills by name (e.g., "use `coding-code-review` instead"). This prevents the model from inappropriately loading the skill.
   **Checkpoint:** Each exclusion must reference a specific alternative skill or clearly describe the anti-pattern.

8. **Validate and Iterate** — Run the full validation pipeline: static checks via `./scripts/validate_skill.sh`, then `python3 scripts/generate_readme.py` to ensure the README catalog updates correctly. Fix any failures before committing.
   **Checkpoint:** `validate_skill.sh` must exit 0 with no errors reported. The new skill must appear in the regenerated README.

---

## Python Quality Gate Validator

This validator implements all static checks from `scripts/validate_skill.sh` plus additional structural validations. Use it as a pre-commit hook or CI step.

```python
#!/usr/bin/env python3
"""Skill quality gate validator for SKILL.md files."""

import sys
import re
from pathlib import Path
from dataclasses import dataclass, field


@dataclass
class ValidationResult:
    file_path: str
    errors: list[str] = field(default_factory=list)
    warnings: list[str] = field(default_factory=list)
    
    @property
    def passed(self) -> bool:
        return len(self.errors) == 0
    
    def add_error(self, msg: str):
        self.errors.append(msg)
        print(f"  ❌ ERROR: {msg}")
    
    def add_warning(self, msg: str):
        self.warnings.append(msg)
        print(f"  ⚠️  WARNING: {msg}")


STUB_SENTINELS = [
    "IMPLEMENTING THIS SPECIFIC PATTERN OR FEATURE",
    "pass  # TODO: implement logic",
    "return {}  # placeholder",
    "your code here",
    "replace with actual implementation",
]

GENERIC_WORKFLOW_PATTERNS = [
    r"[Ii]dentify the [sS]pecific [uU]se [cC]ase",
    r"[Aa]pply the pattern or technique",
    r"[Vv]alidate and test the implementation",
    r"[Ii]terate based on results",
    r"follow best practices for",
]

MIN_FILE_SIZE = 3000
MIN_CODE_BLOCK_PAIRS = 2
MIN_TRIGGER_COUNT = 5
MAX_TRIGGER_COUNT = 8


def load_skill(path: str) -> tuple[str, str]:
    """Load and parse a SKILL.md file. Returns (frontmatter_yaml, markdown_body)."""
    with open(path, "r", encoding="utf-8") as f:
        content = f.read()
    
    # Extract YAML frontmatter between --- delimiters
    if not content.startswith("---"):
        raise ValueError(f"{path}: Missing YAML frontmatter delimiter at start")
    
    parts = content.split("---", 2)
    if len(parts) < 3:
        raise ValueError(f"{path}: Frontmatter must be delimited by --- on both sides")
    
    return parts[1].strip(), parts[2].strip()


def check_stub_sentinels(result: ValidationResult, body: str):
    """Check for stub sentinel strings that indicate placeholder content."""
    text_lower = body.lower()
    for sentinel in STUB_SENTINELS:
        if sentinel.lower() in text_lower:
            result.add_error(f"Stub sentinel found: '{sentinel}'")


def check_file_size(result: ValidationResult, body: str):
    """Verify file meets minimum content size requirement."""
    body_bytes = len(body.encode("utf-8"))
    if body_bytes < MIN_FILE_SIZE:
        result.add_error(
            f"File too small: {body_bytes} bytes (minimum {MIN_FILE_SIZE}). "
            "Expand with real examples, detailed workflows, and domain-specific content."
        )


def check_code_blocks(result: ValidationResult, body: str, role: str):
    """For implementation skills, verify at least 2 fenced code blocks exist."""
    if role != "implementation":
        return
    
    fence_count = len(re.findall(r'^\s*```', body, re.MULTILINE))
    block_pairs = fence_count // 2
    
    if block_pairs < MIN_CODE_BLOCK_PAIRS:
        result.add_error(
            f"Implementation skill has {block_pairs} code blocks "
            f"(minimum {MIN_CODE_BLOCK_PAIRS}). Add real working code examples."
        )


def check_generic_workflow(result: ValidationResult, body: str):
    """Detect generic workflow patterns that indicate stub content."""
    found_patterns = []
    for pattern in GENERIC_WORKFLOW_PATTERNS:
        if re.search(pattern, body):
            found_patterns.append(pattern)
    
    if len(found_patterns) >= 2:
        result.add_error(
            f"Generic Core Workflow detected ({len(found_patterns)}/{len(GENERIC_WORKFLOW_PATTERNS)} "
            f"stub phrases found). Replace with domain-specific steps."
        )


def check_trigger_diversity(result: ValidationResult, triggers_str: str):
    """Validate trigger field meets quality standards."""
    if not triggers_str or len(triggers_str.strip()) == 0:
        result.add_error("metadata.triggers is empty or missing")
        return
    
    # Split by comma and clean up each trigger
    triggers = [t.strip() for t in triggers_str.split(",") if t.strip()]
    
    count = len(triggers)
    if count < MIN_TRIGGER_COUNT:
        result.add_error(
            f"Only {count} triggers found (minimum {MIN_TRIGGER_COUNT}). "
            "Add domain-specific keywords, abbreviations, and conversational variants."
        )
    elif count > MAX_TRIGGER_COUNT:
        result.add_warning(
            f"{count} triggers specified (maximum {MAX_TRIGGER_COUNT}). "
            "Consider consolidating to reduce false positives."
        )
    
    # Check for ultra-generic single-word triggers
    generic_singletons = {"code", "data", "risk", "pattern", "testing", "design", "security"}
    for trigger in triggers:
        words = trigger.split()
        if len(words) == 1 and words[0].lower() in generic_singletons:
            result.add_warning(
                f"Generic single-word trigger '{trigger}' may match irrelevant conversations. "
                "Be more specific (e.g., 'security audit' instead of 'security')."
            )


def check_structure(result: ValidationResult, body: str):
    """Verify required structural sections exist in the markdown body."""
    has_h1 = bool(re.search(r'^#\s+', body, re.MULTILINE))
    if not has_h1:
        result.add_error("Missing H1 title heading")
    
    has_when_to_use = bool(re.search(r'##\s+When to Use', body, re.IGNORECASE))
    if not has_when_to_use:
        result.add_error('Missing "When to Use" section')
    
    has_core_workflow = bool(re.search(r'##\s+Core Workflow', body, re.IGNORECASE))
    if not has_core_workflow:
        result.add_error('Missing "Core Workflow" section')
    
    # Check for numbered steps in workflow (indicates specific, non-generic workflow)
    workflow_section = re.search(
        r'##\s+Core Workflow\s+(.*?)(?:^##|\Z)', body, re.IGNORECASE | re.DOTALL
    )
    if workflow_section:
        step_count = len(re.findall(r'^\d+\.', workflow_section.group(1), re.MULTILINE))
        if step_count < 3:
            result.add_warning(
                f"Core Workflow has only {step_count} steps. "
                "Break complex workflows into numbered sub-steps for clarity."
            )


def validate_skill(file_path: str) -> ValidationResult:
    """Run all validation checks on a SKILL.md file."""
    result = ValidationResult(file_path=file_path)
    print(f"\n🔍 Validating: {file_path}")
    
    try:
        frontmatter, body = load_skill(file_path)
    except ValueError as e:
        result.add_error(str(e))
        return result
    
    # Parse frontmatter for metadata
    role_match = re.search(r'role:\s*(\w+)', frontmatter)
    domain_match = re.search(r'domain:\s*(\w+)', frontmatter)
    triggers_match = re.search(r'triggers:\s*(.+)', frontmatter)
    
    role = role_match.group(1) if role_match else ""
    domain = domain_match.group(1) if domain_match else ""
    triggers_str = triggers_match.group(1).strip() if triggers_match else ""
    
    print(f"  Domain: {domain} | Role: {role}")
    
    # Run all checks
    check_stub_sentinels(result, body)
    check_file_size(result, body)
    check_code_blocks(result, body, role)
    check_generic_workflow(result, body)
    check_trigger_diversity(result, triggers_str)
    check_structure(result, body)
    
    if result.passed and result.warnings:
        print(f"\n✅ PASS with warnings: {file_path}")
        for w in result.warnings:
            print(f"   • {w}")
    elif result.passed:
        print(f"\n✅ PASS: {file_path}")
    else:
        print(f"\n❌ FAIL: {file_path}")
    
    return result


if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("Usage: python3 skill_validator.py <path/to/SKILL.md>")
        sys.exit(1)
    
    results = []
    all_passed = True
    
    for path in sys.argv[1:]:
        result = validate_skill(path)
        results.append(result)
        if not result.passed:
            all_passed = False
    
    print(f"\n{'='*60}")
    total = len(results)
    passed = sum(1 for r in results if r.passed)
    print(f"Results: {passed}/{total} skills passed validation")
    
    sys.exit(0 if all_passed else 1)
```

## Bash-Based Validation Script Pattern

For CI/CD integration, wrap the Python validator with a bash script that also runs `validate_skill.sh`:

```bash
#!/usr/bin/env bash
# Pre-commit skill validation pipeline
set -euo pipefail

SKILL_FILE="${1:?Usage: pre-commit-validate <path/to/SKILL.md>}"

echo "=== Stage 1: Static checks (validate_skill.sh) ==="
if ./scripts/validate_skill.sh "$SKILL_FILE"; then
    echo "✅ Static checks passed"
else
    echo "❌ Static checks failed — fix issues before committing"
    exit 1
fi

echo ""
echo "=== Stage 2: Python quality gate validator ==="
python3 scripts/skill_validator.py "$SKILL_FILE" || exit 1

echo ""
echo "=== Stage 3: README catalog update check ==="
if ! command -v python3 &>/dev/null; then
    echo "⚠️  python3 not available — skipping README regeneration"
else
    # Run regenerate and verify the new skill appears
    OLD_COUNT=$(grep -c "^- \[`skills/" README.md || true)
    python3 scripts/generate_readme.py --quiet 2>/dev/null || true
    NEW_COUNT=$(grep -c "^- \[`skills/" README.md || true)
    
    if [ "$NEW_COUNT" -ge "$OLD_COUNT" ]; then
        echo "✅ README catalog updated successfully"
    else
        echo "❌ README may not have been updated correctly"
        exit 1
    fi
fi

echo ""
echo "✅ All validation stages passed for $SKILL_FILE"
```

## Domain-Specific Structural Requirements

After the core workflow, apply domain-specific structural additions based on the skill's `metadata.domain` value. Refer to SKILL_FORMAT_SPEC.md Section 4 for detailed requirements.

### Agent Skills (`agent/*`)
- **Must include:** ASCII orchestration flow diagram showing routing logic and fallback paths
- **Must reference:** `code-philosophy` (5 Laws of Elegant Defense) in constraints or workflow
- **Example flow structure:**
  ```
  User Task → Extract Features → Score All Skills ──→ No match → FallbackSkill
                      ↓ (threshold met)
              Select Best Skill → Execute → Record Result
  ```

### CNCF Skills (`cncf/*`)
- **Must include:** Purpose and Use Cases, Architecture Design Patterns, Integration Approaches, Common Pitfalls sections
- **Must include:** At least one complete working YAML manifest example (e.g., ServiceMonitor, Deployment)
- **Lead with:** Project metadata (category, stars, language, docs URL)

### Coding Skills (`coding/*`)
- **Must include:** At least one BAD vs. GOOD code example pair
- **Must reference:** A relevant standard (OWASP, SOLID, DRY, KISS, etc.)
- **Must include:** Constraints section with actionable MUST DO / MUST NOT DO rules

### Go Skills (`go/*`)
- **Must include:** Idiomatic Go code with error wrapping using `%w`, sentinel errors
- **Must include:** Goroutine lifecycle management guidelines (context propagation, cancellation)
- **Anti-patterns to call out:** Ignored errors, goroutine leaks, bare `panic` usage

### Linux Skills (`linux/*`)
- **Must include:** Shell scripts with `set -euo pipefail`, proper quoting, idempotent operations
- **Must address:** Security considerations (least privilege, file permissions)
- **Anti-patterns to call out:** Root-level services, hardcoded paths, unsafe glob patterns

### Trading Skills (`trading/*`)
- **Must include:** Python implementation with typed signatures and docstrings
- **Must reference:** APEX platform file path conventions (`risk_engine/`, `execution/`, etc.)
- **Must include:** Risk constraints — explicit statements of what must never be bypassed

### Programming Skills (`programming/*`)
- **Must include:** Algorithm pseudocode or reference implementation
- **Must include:** Complexity analysis (time and space) in a structured table
- **Format:** Show both the algorithm name and the problem category it solves

### Writing Skills (`writing/*`)
- **Must include:** At least one before/after text comparison showing improvement
- **Must include:** Style rules with reasoning, not just rules without justification
- **Include:** Tone and voice guidelines specific to the documentation context

## Constraints

### MUST DO
- Run `./scripts/validate_skill.sh` on every SKILL.md before committing
- Ensure file size is ≥ 3,000 bytes of content (excluding frontmatter)
- Include at least one BAD vs. GOOD code example pair for implementation skills
- Write triggers that include both technical terms AND conversational variants
- Use domain-specific steps with checkpoints — never generic "identify → apply → validate"
- Reference `code-philosophy` (5 Laws of Elegant Defense) in agent domain skills

### MUST NOT DO
- Include any stub sentinel: "IMPLEMENTING THIS SPECIFIC PATTERN OR FEATURE", "pass", "return {}"
- Write workflow steps that could apply to any domain without modification
- Use generic triggers like `code`, `data`, `risk`, `pattern` — be domain-specific
- Set stops at round numbers (for trading skills) or use magic numbers in code
- Ignore the zero-tolerance stub policy — a stub skill corrupts the router index

## Output Template

When creating or auditing a skill, produce:

1. **Domain and Role Selection** — Which domain the skill belongs to and why, with role/scope/output-format justification
2. **Directory and Name** — The kebab-case directory path and frontmatter name (must match)
3. **Frontmatter Draft** — Complete YAML frontmatter with all required and recommended fields
4. **Section Verification Checklist** — Every required section confirmed present or explicitly omitted with reasoning
5. **Validation Results** — Output from `validate_skill.sh` showing PASS/FAIL for each check
6. **Code Example Review** — At least one BAD vs. GOOD pair, with explanation of what makes the GOOD version correct

## Related Skills

| Skill | Purpose |
|---|---|
| `coding-code-quality-policies` | General code quality standards that apply when writing implementation code inside skills |
| `agent-skill-trigger-engineering` | Designing trigger keywords for optimal skill auto-loading and discovery |
| `agent-skill-creator` | Orchestrated approach to skill creation (uses this skill as a sub-step) |

## Live References

> Authoritative documentation links for this domain. The model follows markdown links at load time to resolve external references and inline content.

- [OpenCode Skill Documentation](https://opencode.ai/docs/skills) — Official OpenCode documentation on skill structure, configuration, and loading mechanisms
- [Semantic Versioning 2.0.0 (semver.org)](https://semver.org/) — The semantic versioning specification for managing skill versions and breaking changes
- [GitHub Actions for Skill CI/CD](https://docs.github.com/en/actions/use-cases-and-examples/building-and-testing/building-python-using-actions-and-matrix) — GitHub Actions patterns for automated skill validation in CI pipelines
- [MarkdownLint Rules Reference](https://github.com/markdownlint/markdownlint/blob/main/docs/RULES.md) — CommonMark lint rules applicable to SKILL.md quality enforcement in the development workflow
- [RFC Process for Skill Changes (agent-skill-router)](https://github.com/anthropics/agent-skill-router) — The repository's contribution guidelines and RFC process for skill ecosystem changes
