Skip to main content

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​

ReaderFocus
HumansStep-by-step creation guide, examples
AIMachine-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​

AspectPattern (v3.0.0)
Name{name}
Command/{name}
Directoryskills/{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}
PartDescriptionExamples
roleTeam functionpm, dev, qa, ux, data, growth
domainArea of workprd, plan, test, docs, learn
actionWhat it doeswrite, add, review, create, update

Examples​

Skill NameCommand
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}/:

FileRequiredPurpose
SKILL.mdYesExecution instructions
template.mdNoOutput 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 number
  • slug: 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:

  1. Add Bash(cp:*) to allowed-tools in frontmatter (skip if Bash already present)
  2. 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).
  3. Add image embedding quality check: If images provided: refs use ![alt](...) syntax
  4. Source scripts/lib/asset-handler.sh for 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.sh in 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.sh after 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​

RoleCommon SubdomainsReport Types
pmprd, stories, roadmapprd, story, roadmap
datagtm, analyticsgtm, analytics
devfrontend, backend, stackfe-tasks, be-tasks, stack
uxheatmap, research, designheatmap, research, design
qatest-cases, reportstest-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
---
FieldTypeRequiredDescription
namestringYesMatches directory name
descriptionstringYes1-2 sentence purpose (max 120 chars), must include "Use when/to/for" trigger phrase, no colons
allowed-toolsstringYesComma-separated tool permissions
argument-hintstringYesShows expected input format
licensestringYesLicense 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: or Maps 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.sh to 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 ComplexitySKILL.md TargetMax
Simple (single-phase, few steps)150-300400
Standard (two-phase, multi-step)300-500500
Complex (multi-stack, code generation)400-500600

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​

FlagEffectUse When
disable-model-invocation: trueRemoves from auto-suggestions, saves ~280 tokens/sessionInternal/infrastructure skills not directly user-invoked
context: forkRuns in isolated subagent, saves 30-48K tokensHeavy analysis skills (detect-*) that produce bounded output

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:

PatternUse Case
ReadRead any file
GlobFind files by pattern
GrepSearch file contents
WebSearchResearch best practices
TaskLaunch 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
EditModify 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/**) not Write($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​

SectionLevelPurpose
# {name}H1Title matching skill name
> {tagline}blockquoteOne-line description
## Context FilesH2Files to read before execution
## InputH2How to interpret $ARGUMENTS
# PHASE 1: AnalysisH1Read-only operations
## Pre-Execution ProtocolH2Protocol steps (init, lessons, template, seeding)
# HARD STOPH1Human approval gate
# PHASE 2: GenerationH1Write operations
## Definition of DoneH2Completion 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:

VariableDefaultPurpose
$JAAN_OUTPUTS_DIRjaan-to/outputsGenerated files
$JAAN_TEMPLATES_DIRjaan-to/templatesOutput templates
$JAAN_LEARN_DIRjaan-to/learnLearning files
$JAAN_CONTEXT_DIRjaan-to/contextProject 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​

  1. 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"
  2. 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
  3. 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.md exists: 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:

FieldVariablePurpose
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
Version3.0Template version

Line Limits​

Output TypeTargetMax
PRD150-200300
Test Plan100-150200
API Contract80-120150
Short Report50-80100

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:

CategoryTrigger Keywords
Better Questionsask, question, clarify, confirm, inquire
Edge Casesedge, special, case, handle, scenario
Workflowworkflow, process, step, order, sequence
Common Mistakesavoid, 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 name matching directory
  • Has description with purpose (max 120 chars, no Auto-triggers on:/Maps to: lines)
  • Has description with "Use when" or "Use to" trigger phrase
  • Has description without colons (:)
  • Has allowed-tools with valid tool patterns
  • Has argument-hint showing expected format
  • Has license: PROPRIETARY
  • Skill added to .claude-plugin/marketplace.json plugins[0].skills[]

Body Checklist​

  • Has H1 title matching skill name ({name})
  • Has tagline blockquote
  • Has ## Context Files section
  • Has ## Input section
  • Has # PHASE 1: Analysis section
  • Has ## Step 0: Apply Past Lessons section
  • Has # HARD STOP section
  • Has # PHASE 2: Generation section
  • Has ## Definition of Done section

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 TypeWhenUse For
PreToolUseBefore writeValidate content
PostToolUseAfter writeTrigger 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

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.sh before commit so adapters/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.sh before opening a skill PR
  • Keep SKILL.md focused on execution, not explanation

Back to Extending | Create a Hook