Skill Creation Specification
Complete reference for creating jaan.to skills—for humans and AI.
Overview
A skill is a reusable command that AI executes to produce outputs. This specification defines the structure, files, and patterns required for valid skills.
Audience
| Reader | Focus |
|---|---|
| Humans | Step-by-step creation guide, examples |
| AI | Machine-parseable schemas, validation rules |
Principles
- Two-Phase Workflow — Read-only analysis, then write with approval
- Human-in-the-Loop — Hard stop before any file writes
- Continuous Learning — Every skill reads and contributes to LEARN.md
- Safety First — Tool permissions restrict write paths
Quick Reference
| Aspect | Pattern (v3.0.0) |
|---|---|
| Name | {name} |
| Command | /{name} |
| Directory | skills/{name}/ (plugin) |
| Output | $JAAN_OUTPUTS_DIR/{role}/{domain}/{slug}/ (project) |
| Templates | $JAAN_TEMPLATES_DIR/{name}.template.md (project) |
| Learning | $JAAN_LEARN_DIR/{name}.learn.md (project) |
| Context | $JAAN_CONTEXT_DIR/*.md (project) |
Naming Conventions
Pattern
Role-based skills (for team use):
{role}-{domain}-{action}
Internal skills (for plugin maintenance):
{domain}-{action}
| Part | Description | Examples |
|---|---|---|
| role | Team function | pm, dev, qa, ux, data, growth |
| domain | Area of work | prd, plan, test, docs, learn |
| action | What it does | write, add, review, create, update |
Examples
| Skill Name | Command |
|---|---|
pm-prd-write | /pm-prd-write |
qa-plan-test-matrix | /qa-plan-test-matrix |
docs-create | /docs-create |
backend-api-contract | /backend-api-contract |
Required Files
Every skill needs these files in skills/{name}/:
| File | Required | Purpose |
|---|---|---|
SKILL.md | Yes | Execution instructions |
template.md | No | Output format template |
Learning lessons are stored in $JAAN_LEARN_DIR/{name}.learn.md (managed by the system).
Skill Output Standards
Overview
All jaan.to skills that generate user-facing outputs MUST follow the standardized structure to ensure consistency, discoverability, and maintainability.
Required Structure
jaan-to/outputs/{role}/{subdomain}/{id}-{slug}/
├── {id}-{slug}.md # Main output file
└── {id}-{slug}-{type}.{ext} # Optional companion files
Components
1. ID Generation
Requirement: All outputs must have sequential IDs per subdomain.
Implementation:
source "${CLAUDE_PLUGIN_ROOT}/scripts/lib/id-generator.sh"
SUBDOMAIN_DIR="$JAAN_OUTPUTS_DIR/{role}/{subdomain}"
NEXT_ID=$(generate_next_id "$SUBDOMAIN_DIR")
Example Output: 01, 02, 03, etc.
2. Folder Structure
Requirement: Each output must be in its own folder.
Format: {id}-{slug}/
id: Two-digit sequential numberslug: lowercase-kebab-case from title (max 50 chars)
Example: 01-user-authentication/, 02-payment-flow/
3. Slug Scoping
Requirement: Slugs are unique per subdomain, NOT globally.
Cross-role reuse: The same slug can be used across different role/subdomain combinations.
Example: "user-auth" can exist in:
pm/prd/01-user-auth/(PRD for user authentication)data/gtm/01-user-auth/(GTM tracking for user authentication)frontend/task-breakdown/01-user-auth/(Frontend tasks for user authentication)
Benefit: Natural feature/topic naming across different roles and output types.
4. File Naming
Requirement: All files in folder must use ID prefix.
Main File Format: {id}-{slug}.md
Companion File Format: {id}-{slug}-{type}.{ext}
type: Descriptive suffix (tasks, notes, code, preview, etc.)
Examples:
- Main:
01-user-authentication.md - Auxiliary:
01-user-authentication-tasks.md
5. Index Management
Requirement: Update subdomain README.md after each output.
Implementation:
source "${CLAUDE_PLUGIN_ROOT}/scripts/lib/index-updater.sh"
add_to_index \
"$SUBDOMAIN_DIR/README.md" \
"$NEXT_ID" \
"${NEXT_ID}-${slug}" \
"{Title}" \
"{1-2 sentence executive summary}"
6. Executive Summary
Requirement: All outputs must include Executive Summary section.
Placement: Near the top of the document (after title, before main content).
Format:
## Executive Summary
{1-2 sentence high-level summary of the problem, solution, or findings}
Purpose: Enables quick scanning in index files and cross-referencing.
7. Asset Embedding (Optional)
For skills that accept image/screenshot inputs and generate markdown output:
- Add
Bash(cp:*)toallowed-toolsin frontmatter (skip ifBashalready present) - Add an inline reference pointer in the Write Phase step:
> **Reference**: See `${CLAUDE_PLUGIN_ROOT}/docs/extending/asset-embedding-reference.md`
> for the asset resolution protocol (path detection, copy rules, markdown embedding). - Add image embedding quality check:
If images provided: refs use  syntax - Source
scripts/lib/asset-handler.shfor path detection and resolution functions
See docs/extending/asset-embedding-reference.md for the full protocol.
Implementation Checklist
When creating a new output-generating skill:
- Source
scripts/lib/id-generator.shin Step 5.5 - Generate sequential ID using
generate_next_id() - Create folder:
{subdomain}/{id}-{slug}/ - Name main file:
{id}-{slug}.md - Source
scripts/lib/index-updater.shafter output write - Call
add_to_index()with ID, folder name, title, summary - Include Executive Summary in template
- Preview ID, folder path, and file path before writing
- Confirm index update after writing
Reference Implementation
See pm-prd-write/SKILL.md for complete example.
Role and Subdomain Mapping
| Role | Common Subdomains | Report Types |
|---|---|---|
pm | prd, stories, roadmap | prd, story, roadmap |
data | gtm, analytics | gtm, analytics |
dev | frontend, backend, stack | fe-tasks, be-tasks, stack |
ux | heatmap, research, design | heatmap, research, design |
qa | test-cases, reports | test-cases, report |
Exceptions
Research outputs use flat file structure (not folders):
jaan-to/outputs/research/{id}-{category}-{slug}.md
This is intentional for research summaries due to high volume and simpler structure.
Validation
Run validation script to check compliance:
bash scripts/validate-outputs.sh
Common Mistakes
❌ Wrong: Writing directly to file without folder
echo "$output" > "$JAAN_OUTPUTS_DIR/pm/my-prd.md"
✅ Correct: Create folder, write file with ID prefix
mkdir -p "$OUTPUT_FOLDER"
echo "$output" > "$OUTPUT_FOLDER/${NEXT_ID}-prd-${slug}.md"
❌ Wrong: Hardcoded ID or no ID
FILE="$JAAN_OUTPUTS_DIR/pm/01-my-prd.md" # Hardcoded
FILE="$JAAN_OUTPUTS_DIR/pm/my-prd.md" # No ID
✅ Correct: Generate ID dynamically
NEXT_ID=$(generate_next_id "$SUBDOMAIN_DIR")
FILE="$OUTPUT_FOLDER/${NEXT_ID}-prd-${slug}.md"
❌ Wrong: Forgetting to update index
# Write file only
cat > "$MAIN_FILE" <<EOF
...
EOF
# Missing index update!
✅ Correct: Always update index after write
cat > "$MAIN_FILE" <<EOF
...
EOF
add_to_index "$SUBDOMAIN_DIR/README.md" "$NEXT_ID" "..." "..." "..."
SKILL.md Specification
YAML Frontmatter Schema
Every SKILL.md must begin with YAML frontmatter:
---
name: {skill-name}
description: {1-2 sentence purpose. Keep under 120 chars. Include "Use when" trigger phrase. No colons.}
allowed-tools: {tool-list}
argument-hint: {expected-format}
license: PROPRIETARY
---
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Matches directory name |
description | string | Yes | 1-2 sentence purpose (max 120 chars), must include "Use when/to/for" trigger phrase, no colons |
allowed-tools | string | Yes | Comma-separated tool permissions |
argument-hint | string | Yes | Shows expected input format |
license | string | Yes | License identifier (use PROPRIETARY) |
Skill Naming & Description Standards
Naming: Lowercase alphanumeric + hyphens only, no consecutive hyphens, 1-64 chars, must match directory name.
Description: Include "Use when" trigger phrase, no colons, max 120 chars. Pattern: "<what it does>. Use when <trigger>."
Required fields: license: PROPRIETARY
Marketplace: New skills MUST be added to .claude-plugin/marketplace.json plugins[0].skills[] array as "./skills/{name}".
Description Budget
Claude Code allocates a 15,000 character budget for all skill descriptions in the system prompt. Each skill costs ~109 chars of XML overhead plus the description length. If total exceeds budget, skills get silently dropped.
Rules:
- Keep descriptions under 120 chars (1-2 sentences)
- Do NOT include
Auto-triggers on:orMaps to:lines - Do NOT use
:(colon-space) in descriptions — Claude Code's parser may misinterpret it as a YAML key-value separator, causing the skill to display incorrectly in the command picker - Use single-line YAML format (no
|block scalar needed) - Run
scripts/validate-skills.shto check budget before release
Override: Set SLASH_COMMAND_TOOL_CHAR_BUDGET environment variable to adjust the budget.
Token Optimization Strategy
When skills grow large, use reference extraction to keep SKILL.md within token targets while preserving all content.
Line Targets
| Skill Complexity | SKILL.md Target | Max |
|---|---|---|
| Simple (single-phase, few steps) | 150-300 | 400 |
| Standard (two-phase, multi-step) | 300-500 | 500 |
| Complex (multi-stack, code generation) | 400-500 | 600 |
Reference Extraction Pattern
When a SKILL.md exceeds ~500 lines, extract reference material (not execution instructions) into a dedicated reference file:
Create: docs/extending/{skill-name}-reference.md
Header:
# {Skill Name} — Reference Material
> Extracted reference tables, code templates, and patterns for the `{skill-name}` skill.
> This file is loaded by `{skill-name}` SKILL.md via inline pointers.
> Do not duplicate content back into SKILL.md.
---
Replace extracted section in SKILL.md with inline pointer:
> **Reference**: See `${CLAUDE_PLUGIN_ROOT}/docs/extending/{skill-name}-reference.md` section "{Section Name}" for {brief description}.
What to Extract (reference material)
Full checklist with safety rules:
docs/extending/extraction-safety-checklist.md
- Code template blocks (TypeScript/PHP/Go examples)
- Multi-stack pattern tables (per-language comparison tables)
- CWE/OWASP mapping tables
- Configuration file content examples (.env, .gitignore, docker-compose patterns)
- Anti-pattern lists (when > 10 items)
- Directory layout ASCII trees (when > 10 lines)
What to Keep Inline (execution instructions)
- Phase structure (PHASE 1 / HARD STOP / PHASE 2)
- Step headings and brief instructions
- AskUserQuestion flows
- Tech detection tables (compact, < 10 rows — needed for every invocation)
- Quality checklists
- Definition of Done
- Key generation rules (< 15 lines — critical for every invocation)
Frontmatter Flags for Token Control
| Flag | Effect | Use When |
|---|---|---|
disable-model-invocation: true | Removes from auto-suggestions, saves ~280 tokens/session | Internal/infrastructure skills not directly user-invoked |
context: fork | Runs in isolated subagent, saves 30-48K tokens | Heavy analysis skills (detect-*) that produce bounded output |
Output Guidance (recommended for new skills)
Advisory patterns to minimize token waste in skill responses:
- Default response shape: (1) Outcome (1-2 lines) (2) Decisions (bullets) (3) Next actions
- Escalation: Summary first, offer expansion on request
- Large output: Follow Two-Phase Workflow — preview before writing to
$JAAN_OUTPUTS_DIR/ - Logs: Top 20 + bottom 20 lines + "full log at {path}"
- No repetition: Don't restate user prompt or reprint shown file excerpts
Concise Prose Rules (for new skills)
All new skills MUST follow these writing rules:
- Kill preambles: don't restate the heading in a sentence before the content
- Abbreviate informational placeholders (NOT function params or commit templates)
- DO NOT shorten: full-sentence instructions (encode ordering/hierarchy), multi-line condition lists (encode mutual exclusivity), "Show user" blocks (encode behavioral gates), decision tables, code templates, AskUserQuestion options, examples, Definition of Done
Tool Permission Patterns (v3.0.0)
Always use environment variables for path-based permissions:
| Pattern | Use Case |
|---|---|
Read | Read any file |
Glob | Find files by pattern |
Grep | Search file contents |
WebSearch | Research best practices |
Task | Launch specialized agents |
Write($JAAN_OUTPUTS_DIR/{role}/**) | Write outputs only |
Write($JAAN_TEMPLATES_DIR/**) | Update templates |
Write($JAAN_LEARN_DIR/**) | Update learning files |
Read($JAAN_CONTEXT_DIR/**) | Read project context |
Write(docs/**) | Documentation skills |
Write(skills/**) | Skill development |
Edit | Modify existing files |
Bash(git add:*) | Stage changes |
Bash(git commit:*) | Commit changes |
Bash(git push:*) | Push changes |
Bash(gh pr create:*) | Create pull requests |
v3.0.0 Best Practices:
- ✓ Use
$JAAN_*environment variables (supports path customization) - ✗ Never use hardcoded
jaan-to/paths (breaks customization) - ✓ Be specific:
Write($JAAN_OUTPUTS_DIR/pm/**)notWrite($JAAN_OUTPUTS_DIR/**) - ✗ Never use
Write(**)(too broad, security risk)
Markdown Body Structure (v3.0.0)
After frontmatter, SKILL.md follows this structure:
# {name}
> {One-line purpose}
## Context Files
Read these before execution:
- `$JAAN_CONTEXT_DIR/config.md` - Configuration
- `$JAAN_TEMPLATES_DIR/{name}.template.md` - Output template
- `$JAAN_LEARN_DIR/{name}.learn.md` - Past lessons (loaded in Pre-Execution)
- `$JAAN_CONTEXT_DIR/tech.md` - Tech stack (if skill is tech-aware)
## Input
**{Input Name}**: $ARGUMENTS
{Instructions for interpreting input}
---
# PHASE 1: Analysis (Read-Only)
## Pre-Execution Protocol
**MANDATORY** — Read and execute ALL steps in: `${CLAUDE_PLUGIN_ROOT}/docs/extending/pre-execution-protocol.md`
Skill name: `{name}`
Execute: Step 0 (Init Guard) → A (Load Lessons) → B (Resolve Template) → C (Offer Template Seeding)
## Step 1: Gather Information
{Questions to ask user}
## Step 2: Plan Structure
{How to organize the output}
---
# HARD STOP - Human Review Gate
{Preview what will be done}
> "Ready to proceed? [y/n]"
**Do NOT proceed to Phase 2 without explicit approval.**
---
# PHASE 2: Generation (Write Phase)
## Step 3: Generate Content
Use template from: `$JAAN_TEMPLATES_DIR/{name}.template.md`
{How to create the output}
## Step 4: Quality Check
Before preview, verify:
- [ ] {Check 1}
- [ ] {Check 2}
- [ ] {Check 3}
If any check fails, revise before preview.
## Step 5: Preview & Approval
Show complete output and ask:
> "Write to `$JAAN_OUTPUTS_DIR/{role}/{domain}/{slug}/{filename}`? [y/n]"
## Step 6: Write Output
If approved:
1. Generate slug from input: lowercase, hyphens, no special chars
2. Create path: `$JAAN_OUTPUTS_DIR/{role}/{domain}/{slug}/`
3. Write file: `$JAAN_OUTPUTS_DIR/{role}/{domain}/{slug}/{filename}`
4. Confirm: "Written to {path}"
## Step 7: Capture Feedback
> "Any feedback? [y/n]"
If yes:
> "[1] Fix now [2] Learn for future [3] Both"
- **Option 1**: Update output, re-preview, re-write
- **Option 2**: Run `/learn-add {skill-name} "{feedback}"`
- **Option 3**: Do both
---
## Definition of Done
- [ ] {Criterion 1}
- [ ] {Criterion 2}
- [ ] User has approved final result
Required Sections
| Section | Level | Purpose |
|---|---|---|
# {name} | H1 | Title matching skill name |
> {tagline} | blockquote | One-line description |
## Context Files | H2 | Files to read before execution |
## Input | H2 | How to interpret $ARGUMENTS |
# PHASE 1: Analysis | H1 | Read-only operations |
## Pre-Execution Protocol | H2 | Protocol steps (init, lessons, template, seeding) |
# HARD STOP | H1 | Human approval gate |
# PHASE 2: Generation | H1 | Write operations |
## Definition of Done | H2 | Completion checklist |
v3.0.0 Configuration System
Overview
v3.0.0 introduces a multi-layer configuration system that allows path customization while maintaining backward compatibility.
Environment Variables
Skills use environment variables for all paths:
| Variable | Default | Purpose |
|---|---|---|
$JAAN_OUTPUTS_DIR | jaan-to/outputs | Generated files |
$JAAN_TEMPLATES_DIR | jaan-to/templates | Output templates |
$JAAN_LEARN_DIR | jaan-to/learn | Learning files |
$JAAN_CONTEXT_DIR | jaan-to/context | Project context |
Key Benefits:
- Users can customize paths via
jaan-to/config/settings.yaml - Skills work in any project structure (monorepos, custom layouts)
- Paths resolve automatically at runtime
Configuration Layers
-
Plugin Defaults (
config/defaults.yaml):version: "3.0"
paths_templates: "jaan-to/templates"
paths_learning: "jaan-to/learn"
paths_context: "jaan-to/context"
paths_outputs: "jaan-to/outputs" -
Project Settings (
jaan-to/config/settings.yaml):version: "3.0"
# Path customization (optional)
paths_outputs: "artifacts/generated"
paths_templates: "docs/templates"
# Template customization (optional)
templates_pm-prd-write_path: "./custom/enterprise-prd.md"
# Learning strategy (optional)
learning_strategy: "merge" # Options: merge, override -
Runtime Resolution:
- Project settings override plugin defaults
- Environment variables reflect final resolved paths
- Skills use variables, never hardcoded paths
Path Customization Example
Default behavior (zero config):
# Skill writes to:
$JAAN_OUTPUTS_DIR/pm/feature-name/prd.md
# Resolves to:
jaan-to/outputs/pm/feature-name/prd.md
Custom paths (via settings.yaml):
paths_outputs: "build/artifacts"
# Same skill command
# Now writes to:
build/artifacts/pm/feature-name/prd.md
Migration from v2.x
v2.x pattern (deprecated):
allowed-tools: Write(jaan-to/outputs/**)
Create path: `jaan-to/outputs/pm/{slug}/`
v3.0.0 pattern (current):
allowed-tools: Write($JAAN_OUTPUTS_DIR/pm/**)
Create path: `$JAAN_OUTPUTS_DIR/pm/{slug}/`
Migration:
/skill-update {skill-name}
# → Select option [8] Migrate to v3.0.0
Template Variables (v3.0.0)
Overview
Templates support four types of variables for dynamic content generation.
1. Field Variables
Basic placeholder substitution:
# {{title}}
> Generated by jaan.to | {{date}}
> Author: {{author}}
## Problem Statement
{{problem}}
## Solution Overview
{{solution}}
Usage in SKILL.md:
## Step 3: Generate Content
Fill template variables:
- `{{title}}` - Feature name from input
- `{{date}}` - Current date (YYYY-MM-DD)
- `{{author}}` - User's git name or "jaan.to"
- `{{problem}}` - Problem statement from Step 1
- `{{solution}}` - Solution overview from Step 1
2. Environment Variables
Access runtime paths:
## Output Location
This file was generated at:
{{env:JAAN_OUTPUTS_DIR}}/{{role}}/{{domain}}/
Customizable via `jaan-to/config/settings.yaml`.
Supported variables:
{{env:JAAN_OUTPUTS_DIR}}{{env:JAAN_TEMPLATES_DIR}}{{env:JAAN_CONTEXT_DIR}}{{env:JAAN_LEARN_DIR}}{{env:CUSTOM_VAR}}- Any shell environment variable
3. Configuration Variables
Access project configuration:
## Configuration
Template source: {{config:paths_templates}}
Learning strategy: {{config:learning_strategy}}
Usage:
{{config:paths_templates}}- From settings.yaml{{config:paths_outputs}}- From settings.yaml{{config:custom_field}}- Any key from settings.yaml
4. Section Imports
Import markdown sections from context files:
## Technical Context
**Stack**:
{{import:$JAAN_CONTEXT_DIR/tech.md#current-stack}}
**Constraints**:
{{import:$JAAN_CONTEXT_DIR/tech.md#constraints}}
**Common Patterns**:
{{import:$JAAN_CONTEXT_DIR/tech.md#patterns}}
Syntax:
{{import:$JAAN_CONTEXT_DIR/{file}#{anchor}}}
Standard Anchors (tech.md):
#current-stack- Languages, frameworks, databases#frameworks- Framework-specific details#constraints- Technical constraints and requirements#versioning- API versioning, deprecation policies#patterns- Common patterns (auth, errors, data access)#tech-debt- Known technical debt items
Complete Template Example
# {{title}}
> Generated by jaan.to | {{date}}
> Author: {{author}}
---
## Problem Statement
{{problem}}
## Solution Overview
{{solution}}
## Success Metrics
| Metric | Current | Target | Measurement |
|--------|---------|--------|-------------|
{{metrics_table}}
## Technical Context
**Stack**:
{{import:$JAAN_CONTEXT_DIR/tech.md#current-stack}}
**Constraints**:
{{import:$JAAN_CONTEXT_DIR/tech.md#constraints}}
## Scope
### In Scope
{{in_scope}}
### Out of Scope
{{out_of_scope}}
## User Stories
{{user_stories}}
---
## Metadata
| Field | Value |
|-------|-------|
| Generated | {{date}} |
| Output Path | {{env:JAAN_OUTPUTS_DIR}}/{{role}}/{{domain}}/ |
| Skill | {{skill_name}} |
| Version | 3.0 |
| Status | Draft |
Tech Stack Integration
When to Use
Skills should be "tech-aware" when they:
- Generate code or technical specifications
- Reference frameworks or languages
- Need to comply with technical constraints
- Create implementation plans
Implementation Pattern
1. Declare in Context Files:
## Context Files
- `$JAAN_CONTEXT_DIR/tech.md` - Tech stack (if exists)
2. Read in Pre-Execution or Step 1:
## Pre-Execution Protocol
**MANDATORY** — Read and execute ALL steps in: `${CLAUDE_PLUGIN_ROOT}/docs/extending/pre-execution-protocol.md`
Skill name: `{name}`
Execute: Step 0 (Init Guard) → A (Load Lessons) → B (Resolve Template) → C (Offer Template Seeding)
3. Use in Generation:
## Step 3: Generate PRD
If tech.md exists:
1. Reference appropriate tech stack in User Stories:
- Backend: "API endpoint in {{backend_framework}}"
- Frontend: "UI component in {{frontend_framework}}"
- Mobile: "{{mobile_platform}} screen"
2. Include Technical Constraints section:
- Import: `{{import:$JAAN_CONTEXT_DIR/tech.md#constraints}}`
3. Mention relevant frameworks from tech.md in Implementation Notes
4. Update Template:
## Technical Context
**Stack**:
{{import:$JAAN_CONTEXT_DIR/tech.md#current-stack}}
**Constraints**:
{{import:$JAAN_CONTEXT_DIR/tech.md#constraints}}
**Relevant Patterns**:
{{import:$JAAN_CONTEXT_DIR/tech.md#patterns}}
tech.md Structure
Skills expect this structure:
# Technology Stack
## Current Stack \{#current-stack}
### Backend
- **Language**: Python 3.11
- **Framework**: FastAPI 0.104
- **Database**: PostgreSQL 15
### Frontend
- **Language**: TypeScript 5.2
- **Framework**: React 18 + Next.js 14
### Mobile
- **iOS**: Swift 5.9 + SwiftUI
- **Android**: Kotlin 1.9 + Jetpack Compose
## Frameworks \{#frameworks}
### API Development
- FastAPI (REST endpoints)
- Pydantic (validation)
- SQLAlchemy (ORM)
## Technical Constraints \{#constraints}
1. **All APIs must return JSON:API format**
2. **Mobile apps must work offline**
3. **Sub-200ms p95 latency**
## Common Patterns \{#patterns}
### Authentication
- OAuth2 + JWT (15min access, 7d refresh)
### Error Handling
- Structured errors with error codes
## Tech Debt \{#tech-debt}
- [ ] Migrate Python 3.11 → 3.12 (Q3 2024)
- [ ] Split monolith → microservices (Q4 2024)
Benefits
Without tech integration:
## User Stories
1. User can search for products
2. User can add products to cart
3. User can checkout
With tech integration:
## User Stories
1. **Search Products**
- Frontend: Search UI in React with debounced input
- Backend: GET /v1/products?q= endpoint in FastAPI
- Constraint: Sub-200ms response time
2. **Add to Cart**
- Frontend: Redux cart state management
- Backend: POST /v1/cart/items in FastAPI
- Mobile: Offline-first with sync on reconnect
3. **Checkout**
- Frontend: Next.js server components for SSR
- Backend: OAuth2 authentication required
- Constraint: JSON:API format response
Learning Merge Strategy
Overview
v3.0.0 supports two learning strategies: merge (default) and override.
Merge Strategy (Default)
Combines lessons from plugin defaults + project customizations:
Plugin LEARN.md (skills/{name}/LEARN.md):
## Better Questions
- Plugin question 1
- Plugin question 2
## Workflow
- Plugin workflow step 1
Project LEARN.md ($JAAN_LEARN_DIR/{name}.learn.md):
## Better Questions
- Project-specific question 1
## Edge Cases
- Project edge case 1
Runtime merged view:
## Better Questions
<!-- source: plugin -->
- Plugin question 1
- Plugin question 2
<!-- source: project -->
- Project-specific question 1
## Edge Cases
<!-- source: project -->
- Project edge case 1
## Workflow
<!-- source: plugin -->
- Plugin workflow step 1
Override Strategy
Project lessons completely replace plugin defaults:
# jaan-to/config/settings.yaml
learning_strategy: "override"
- If
$JAAN_LEARN_DIR/{name}.learn.mdexists: use project only - If not: fall back to plugin
LEARN.md
Configuration
Enable merge (default):
# jaan-to/config/settings.yaml
learning_strategy: "merge"
Enable override:
learning_strategy: "override"
Use Cases
Merge: Teams want to keep plugin best practices + add company-specific lessons Override: Teams want full control over all lessons (replace plugin defaults)
template.md Specification (v3.0.0)
Templates define output format with variable placeholders.
Variable Syntax
v3.0.0 uses {{double-brace}} syntax for all variables:
# {{title}}
> Generated by jaan.to | {{date}}
> Author: {{author}}
---
## Section Name
{{section_content}}
## Technical Context
**Stack**:
{{import:$JAAN_CONTEXT_DIR/tech.md#current-stack}}
---
## Metadata
| Field | Value |
|-------|-------|
| Created | {{date}} |
| Output Path | {{env:JAAN_OUTPUTS_DIR}}/{{role}}/{{domain}}/ |
| Skill | {{skill_name}} |
| Status | {{status}} |
| Version | 3.0 |
Required Metadata
All templates should include a Metadata table with:
| Field | Variable | Purpose |
|---|---|---|
| Created | {{date}} | Generation date (YYYY-MM-DD) |
| Output Path | {{env:JAAN_OUTPUTS_DIR}}/... | Where file was written |
| Skill | {{skill_name}} | Which skill generated this |
| Status | {{status}} | Draft/Review/Final |
| Version | 3.0 | Template version |
Line Limits
| Output Type | Target | Max |
|---|---|---|
| PRD | 150-200 | 300 |
| Test Plan | 100-150 | 200 |
| API Contract | 80-120 | 150 |
| Short Report | 50-80 | 100 |
LEARN.md Specification
Every skill accumulates lessons in LEARN.md.
Structure
# Lessons: {skill-name}
> Last updated: {YYYY-MM-DD}
Accumulated lessons from past executions.
---
## Better Questions
Questions to ask during information gathering:
- {lesson}
## Edge Cases
Special cases to check and handle:
- {lesson}
## Workflow
Process improvements:
- {lesson}
## Common Mistakes
Things to avoid:
- {lesson}
Auto-Categorization Keywords
When adding lessons via /learn-add, category is detected by keywords:
| Category | Trigger Keywords |
|---|---|
| Better Questions | ask, question, clarify, confirm, inquire |
| Edge Cases | edge, special, case, handle, scenario |
| Workflow | workflow, process, step, order, sequence |
| Common Mistakes | avoid, mistake, wrong, don't, never |
Empty Starter
New skills start with empty sections:
# Lessons: {skill-name}
> Last updated: {date}
Accumulated lessons from past executions.
---
## Better Questions
(none yet)
## Edge Cases
(none yet)
## Workflow
(none yet)
## Common Mistakes
(none yet)
Validation Rules
Frontmatter Checklist
- Has
namematching directory - Has
descriptionwith purpose (max 120 chars, noAuto-triggers on:/Maps to:lines) - Has
descriptionwith "Use when" or "Use to" trigger phrase - Has
descriptionwithout colons (:) - Has
allowed-toolswith valid tool patterns - Has
argument-hintshowing expected format - Has
license: PROPRIETARY - Skill added to
.claude-plugin/marketplace.jsonplugins[0].skills[]
Body Checklist
- Has H1 title matching skill name (
{name}) - Has tagline blockquote
- Has
## Context Filessection - Has
## Inputsection - Has
# PHASE 1: Analysissection - Has
## Step 0: Apply Past Lessonssection - Has
# HARD STOPsection - Has
# PHASE 2: Generationsection - Has
## Definition of Donesection
Trust Rules
- Write paths must be sandboxed (
jaan-to/**,docs/**, etc.) - Never allow
Write(*)or unrestricted write - Git operations must be pattern-restricted
- Always require human approval before writes
Integration Patterns (v3.0.0)
Stack Context
Skills should read context files when relevant:
## Context Files
Read these before execution:
- `$JAAN_CONTEXT_DIR/config.md` - Configuration
- `$JAAN_CONTEXT_DIR/tech.md` - Technology context
- `$JAAN_CONTEXT_DIR/team.md` - Team structure and norms
- `$JAAN_CONTEXT_DIR/integrations.md` - External tool config
- `$JAAN_TEMPLATES_DIR/{name}.template.md` - Output template
- `$JAAN_LEARN_DIR/{name}.learn.md` - Past lessons
Hook Integration
Skills can trigger validation hooks:
| Hook Type | When | Use For |
|---|---|---|
PreToolUse | Before write | Validate content |
PostToolUse | After write | Trigger feedback |
Feedback Capture
End every skill with feedback option:
## Step 7: Capture Feedback
After writing:
> "Any feedback? [y/n]"
If yes:
- Run `/learn-add {skill-name} "{feedback}"`
Config Registration
Register new skills in jaan-to/context/config.md:
## Skills
| Skill | Command | Description |
|-------|---------|-------------|
| `pm-prd-write` | `/pm-prd-write` | Generate PRD |
| `your-new-skill` | `/your-new-skill` | Your description |
Examples
Minimal Skill (v3.0.0)
Simplest valid skill structure:
skills/example-minimal-demo/SKILL.md:
---
name: example-minimal-demo
description: Demonstrate minimal skill structure.
allowed-tools: Read, Write($JAAN_OUTPUTS_DIR/example/**)
argument-hint: [topic]
---
# example-minimal-demo
> Demonstrate minimal skill structure.
## Context Files
- `$JAAN_LEARN_DIR/example-minimal-demo.learn.md` - Past lessons (loaded in Pre-Execution)
## Input
**Topic**: $ARGUMENTS
---
# PHASE 1: Analysis (Read-Only)
## Pre-Execution Protocol
**MANDATORY** — Read and execute ALL steps in: `${CLAUDE_PLUGIN_ROOT}/docs/extending/pre-execution-protocol.md`
Skill name: `example-minimal-demo`
Execute: Step 0 (Init Guard) → A (Load Lessons) → B (Resolve Template) → C (Offer Template Seeding)
## Step 1: Gather Information
Ask: "What should the demo cover?"
---
# HARD STOP - Human Review Gate
> "Ready to generate demo for '{topic}'? [y/n]"
**Do NOT proceed to Phase 2 without explicit approval.**
---
# PHASE 2: Generation (Write Phase)
## Step 3: Generate Content
Create simple markdown output with:
- Title based on topic
- Current date
- Demo content
## Step 4: Quality Check
- [ ] Has title
- [ ] Has content
- [ ] Has metadata section
If any check fails, revise before preview.
## Step 5: Preview & Approval
Show complete output and ask:
> "Write to `$JAAN_OUTPUTS_DIR/example/minimal/{slug}/demo.md`? [y/n]"
## Step 6: Write Output
If approved:
1. Generate slug from topic: lowercase, hyphens
2. Create path: `$JAAN_OUTPUTS_DIR/example/minimal/{slug}/`
3. Write file: `$JAAN_OUTPUTS_DIR/example/minimal/{slug}/demo.md`
4. Confirm: "Written to {path}"
## Step 7: Capture Feedback
> "Any feedback? [y/n]"
If yes:
> "[1] Fix now [2] Learn for future [3] Both"
- **Option 1**: Update output, re-preview, re-write
- **Option 2**: Run `/learn-add example-minimal-demo "{feedback}"`
- **Option 3**: Do both
---
## Definition of Done
- [ ] Demo file written to correct path
- [ ] All quality checks pass
- [ ] User approved final result
Full-Featured Skill (v3.0.0)
Complete skill with all v3.0.0 patterns:
skills/qa-test-matrix/SKILL.md:
---
name: qa-test-matrix
description: Generate comprehensive test matrix from feature requirements.
allowed-tools: Read, Glob, Grep, Task, WebSearch, Write($JAAN_OUTPUTS_DIR/qa/**)
argument-hint: [feature-name-or-prd-path]
---
# qa-test-matrix
> Generate comprehensive test matrix from feature requirements.
## Context Files
Read these before execution:
- `$JAAN_CONTEXT_DIR/config.md` - Configuration
- `$JAAN_CONTEXT_DIR/boundaries.md` - Safety rules
- `$JAAN_TEMPLATES_DIR/jaan-to-qa-test-matrix.template.md` - Output template
- `$JAAN_LEARN_DIR/jaan-to-qa-test-matrix.learn.md` - Past lessons (loaded in Pre-Execution)
- `$JAAN_CONTEXT_DIR/tech.md` - Test frameworks and tools (if exists)
- `$JAAN_CONTEXT_DIR/team.md` - QA capacity and norms (if exists)
## Input
**Feature**: $ARGUMENTS
If path to PRD provided, read it. Otherwise, ask for requirements.
---
# PHASE 1: Analysis (Read-Only)
## Thinking Mode
ultrathink
Use extended reasoning for:
- Analyzing test coverage gaps
- Planning comprehensive test scenarios
- Ensuring edge case coverage
## Pre-Execution Protocol
**MANDATORY** — Read and execute ALL steps in: `${CLAUDE_PLUGIN_ROOT}/docs/extending/pre-execution-protocol.md`
Skill name: `qa-test-matrix`
Execute: Step 0 (Init Guard) → A (Load Lessons) → B (Resolve Template) → C (Offer Template Seeding)
Also read tech context if available:
- `$JAAN_CONTEXT_DIR/tech.md` - Know test frameworks and tooling
## Step 1: Gather Information
Ask these questions (+ any from LEARN.md):
1. "What are the critical user journeys?"
2. "What browsers/devices need coverage?"
3. "What's the priority order for test cases?"
4. "Are there any known edge cases?"
5. "What test automation frameworks are in use?" (if tech.md not available)
## Step 2: Plan Matrix Structure
Organize by:
- Test categories (functional, integration, edge cases, performance)
- Priority levels (P0-Critical, P1-High, P2-Medium)
- Coverage areas (happy path, error handling, edge cases, security)
- Test types (manual, automated, E2E)
If tech.md exists, include:
- Framework-specific test patterns
- Browser/device matrix from tech constraints
- Performance targets from tech.md
---
# HARD STOP - Human Review Gate
Show planned structure:
> "Test matrix will cover:
> - {n} functional tests (P0: {x}, P1: {y}, P2: {z})
> - {n} integration tests
> - {n} edge case tests
> - {n} performance tests (if tech constraints exist)
>
> Test frameworks: {from tech.md or user input}
> Browsers/devices: {from tech.md or user input}
>
> Proceed with generation? [y/n]"
**Do NOT proceed to Phase 2 without explicit approval.**
---
# PHASE 2: Generation (Write Phase)
## Step 3: Generate Test Matrix
Use template from: `$JAAN_TEMPLATES_DIR/jaan-to-qa-test-matrix.template.md`
Fill variables:
- `{{title}}` - Feature name
- `{{date}}` - Current date
- `{{test_categories}}` - Generated test categories
- `{{priority_breakdown}}` - P0/P1/P2 counts
If tech.md exists, include:
- `{{import:$JAAN_CONTEXT_DIR/tech.md#frameworks}}` in Test Tools section
- `{{import:$JAAN_CONTEXT_DIR/tech.md#constraints}}` in Constraints section
## Step 4: Quality Check
Before preview, verify:
- [ ] Has at least 3 test categories
- [ ] Has priority levels assigned (P0/P1/P2)
- [ ] Has clear pass/fail criteria for each test
- [ ] Has coverage for happy path AND error cases
- [ ] Has edge cases documented
- [ ] If tech.md exists: references correct test frameworks
- [ ] If tech.md exists: includes performance targets
If any check fails, revise before preview.
## Step 5: Preview & Approval
Show complete matrix and ask:
> "Write to `$JAAN_OUTPUTS_DIR/qa/test-matrix/{slug}/matrix.md`? [y/n]"
## Step 6: Write Output
If approved:
1. Generate slug from feature name: lowercase, hyphens, no special chars, max 50 chars
2. Create path: `$JAAN_OUTPUTS_DIR/qa/test-matrix/{slug}/`
3. Write file: `$JAAN_OUTPUTS_DIR/qa/test-matrix/{slug}/matrix.md`
4. Confirm: "Test matrix written to {path}"
## Step 7: Capture Feedback
> "Any feedback on the test matrix? [y/n]"
If yes:
> "[1] Fix now [2] Learn for future [3] Both"
- **Option 1**: Update matrix, re-preview, re-write
- **Option 2**: Run `/learn-add qa-test-matrix "{feedback}"`
- **Option 3**: Do both
---
## Definition of Done
- [ ] Test matrix file exists at correct path
- [ ] All quality checks pass
- [ ] Tech stack integrated (if tech.md available)
- [ ] Priority levels assigned to all tests
- [ ] Edge cases documented
- [ ] User approved final content
v3.0.0 Migration Checklist
Automated Migration
Use the skill validator for migration:
/skill-update {skill-name}
# → Select option [8] Migrate to v3.0.0
# → Choose migration approach (auto-fix, interactive, guidance)
Manual Migration Steps
If migrating manually:
1. Update Frontmatter Permissions
# Before (v2.x)
allowed-tools: Write(jaan-to/outputs/**), Read(jaan-to/context/**)
# After (v3.0.0)
allowed-tools: Write($JAAN_OUTPUTS_DIR/**), Read($JAAN_CONTEXT_DIR/**)
Find & Replace:
Write(jaan-to/outputs/**)→Write($JAAN_OUTPUTS_DIR/**)Read(jaan-to/context/**)→Read($JAAN_CONTEXT_DIR/**)Edit(jaan-to/templates/**)→Edit($JAAN_TEMPLATES_DIR/**)Write(jaan-to/learn/**)→Write($JAAN_LEARN_DIR/**)Edit(jaan-to/**)→Edit($JAAN_TEMPLATES_DIR/**), Edit($JAAN_LEARN_DIR/**)
2. Update Context Files Section
# Before (v2.x)
## Context Files
- `jaan-to/context/config.md` - Configuration
- `jaan-to/learn/{name}.learn.md` - Past lessons
- `skills/{name}/template.md` - Template
# After (v3.0.0)
## Context Files
- `$JAAN_CONTEXT_DIR/config.md` - Configuration
- `$JAAN_LEARN_DIR/{name}.learn.md` - Past lessons (loaded in Pre-Execution)
- `$JAAN_TEMPLATES_DIR/{name}.template.md` - Output template
- `$JAAN_CONTEXT_DIR/tech.md` - Tech stack (if tech-aware)
Find & Replace:
`jaan-to/context/→`$JAAN_CONTEXT_DIR/`jaan-to/learn/→`$JAAN_LEARN_DIR/`jaan-to/templates/→`$JAAN_TEMPLATES_DIR/`skills/{name}/template.md`→`$JAAN_TEMPLATES_DIR/{name}.template.md`
3. Update Pre-Execution Section
# Before (v2.x)
## Step 0: Apply Past Lessons
Read `jaan-to/learn/{name}.learn.md` if it exists:
# After (v3.0.0+)
## Pre-Execution Protocol
**MANDATORY** — Read and execute ALL steps in: `${CLAUDE_PLUGIN_ROOT}/docs/extending/pre-execution-protocol.md`
Skill name: `{name}`
Execute: Step 0 (Init Guard) → A (Load Lessons) → B (Resolve Template) → C (Offer Template Seeding)
Changes:
- Rename "Step 0" → "Pre-Execution Protocol"
- Delegate to shared protocol document for all pre-execution steps
- Add explicit step enumeration to ensure all steps execute
4. Update Template References
# Before (v2.x)
Use template from `skills/{name}/template.md`
# After (v3.0.0)
Use template from: `$JAAN_TEMPLATES_DIR/{name}.template.md`
5. Update Output Paths
# Before (v2.x)
Write to `jaan-to/outputs/{role}/{domain}/{slug}/`
# After (v3.0.0)
Write to `$JAAN_OUTPUTS_DIR/{role}/{domain}/{slug}/`
Find & Replace:
`jaan-to/outputs/→`$JAAN_OUTPUTS_DIR/Create path: jaan-to/outputs/→Create path: $JAAN_OUTPUTS_DIR/
6. Update template.md (if exists)
# Before (v2.x)
## Metadata
- Created: {date}
- Skill: {skill_name}
# After (v3.0.0)
## Metadata
| Field | Value |
|-------|-------|
| Created | {{date}} |
| Output Path | {{env:JAAN_OUTPUTS_DIR}}/{{role}}/{{domain}}/ |
| Skill | {{skill_name}} |
| Version | 3.0 |
Changes:
- Replace
{field}→{{field}}(double braces) - Add environment variable:
{{env:JAAN_OUTPUTS_DIR}} - Add version field
- Convert to table format
7. Validate Migration
After migration, run validation:
# Use skill validator
/skill-update {skill-name}
Check v3.0.0 compliance:
- ✓ V3.1: Frontmatter uses
$JAAN_*variables - ✓ V3.2: Context paths use
$JAAN_* - ✓ V3.3: Learning path uses
$JAAN_LEARN_DIR - ✓ V3.4: Template path uses
$JAAN_TEMPLATES_DIR - ✓ V3.5: Output paths use
$JAAN_OUTPUTS_DIR - ✓ V3.6: template.md uses
{{double-brace}}syntax - ✓ V3.7: Tech integration (if applicable)
If all checks pass: v3.0.0 Compliant ✓
Rollback Plan
If issues occur after migration:
# Restore backups created by auto-fix script
mv skills/{name}/SKILL.md.v2.backup skills/{name}/SKILL.md
mv skills/{name}/template.md.v2.backup skills/{name}/template.md
Testing Post-Migration
After migration, test the skill:
# Test with example input
/{skill-name} "{example-input}"
# Verify:
# 1. Skill runs without errors
# 2. Output written to correct path
# 3. Template variables resolved correctly
# 4. Tech integration works (if applicable)
Creation Checklist
Before Creating
- Check if similar skill exists
- Determine role and domain
- Identify required tool permissions
- Plan the output format
After Creating
- SKILL.md passes validation checklist
- Template exists (if skill has structured output)
- Skill registered in
context/config.md - Documentation added to
docs/skills/{role}/ - Run
bash scripts/prepare-skill-pr.shbefore commit soadapters/codex/skillpack/stays in sync
Tips
- Start with fewer questions—add more via
/learn-add - Match output format to team expectations
- Read stack context instead of asking redundant questions
- Test with real scenarios before committing
- Always run
bash scripts/prepare-skill-pr.shbefore opening a skill PR - Keep SKILL.md focused on execution, not explanation