Best Practices
Guidelines and patterns for creating high-quality YMD/PMD files.
YMD Best Practices
Metadata
Use Descriptive IDs
# ✅ GOOD
meta:
id: code_review_assistant
# ❌ BAD
meta:
id: cr_assist
Why: Clear, descriptive IDs make the purpose obvious.
Follow Semantic Versioning
meta:
version: 1.0.0 # Initial release
version: 1.1.0 # New feature (backward compatible)
version: 2.0.0 # Breaking change
Why: Tracks changes and compatibility clearly.
Meaningful Titles
# ✅ GOOD
meta:
title: Comprehensive Code Review Assistant
# ❌ BAD
meta:
title: Assistant
Why: Titles help users understand purpose at a glance.
Structure
Keep YMD Thin
# ✅ GOOD - Mostly includes
system: |
{% include "roles/senior_dev.pmd" %}
review_focus: |
{% include "checklists/quality.pmd" %}
{% include "checklists/security.pmd" %}
# ❌ BAD - Large inline content
system: |
You are a senior developer...
[45 lines of content]
Why: Reusability and maintainability improve with extracted components.
Use Custom Sections Appropriately
# ✅ GOOD - Clear, domain-specific sections
context: |
Working on
api_principles: |
{% include "principles/rest_principles.pmd" %}
security_requirements: |
{% include "security/api_security.pmd" %}
# ❌ BAD - Everything in instructions
instructions: |
Context: Working on
API Principles: ...
Security Requirements: ...
Why: Custom sections provide better organization and clarity.
Document Expected Variables
{# Expected variables:
- project_type: string - Type of project
- language: string - Programming language
- code: string - Code to review
#}
meta:
id: code_reviewer
...
Why: Makes it clear what variables are needed at render time.
Organization
Logical Section Order
# ✅ GOOD - Logical flow
meta: ...
system: ... # Who
context: ... # Where/when
instructions: ... # What
expected_output: ... # How
user: ... # Input
# ❌ BAD - Random order
meta: ...
user: ...
system: ...
expected_output: ...
Why: Natural reading order improves understanding.
PMD Best Practices
Single Responsibility
One Clear Purpose
<!-- ✅ GOOD - Single responsibility -->
You are an expert in {{ domain }}.
Your approach:
- Clear, technical answers
- Best practices focus
<!-- ❌ BAD - Multiple responsibilities -->
You are an expert in {{ domain }}.
Your approach: ...
Also, here are some checklists:
- [ ] Check 1
- [ ] Check 2
And output format:
Return as JSON...
Why: Single responsibility makes components more reusable.
Extract Related Concerns
<!-- If mixing concerns, split into multiple PMDs -->
roles/expert.pmd # Just the role
checklists/quality.pmd # Just the checklist
formats/json_response.pmd # Just the format
Naming
Descriptive Filenames
# ✅ GOOD
roles/senior_python_developer.pmd
checklists/api_security_review.pmd
formats/markdown_documentation.pmd
# ❌ BAD
roles/dev.pmd
checklists/check.pmd
formats/format.pmd
Why: Names should explain the component’s purpose.
Follow Conventions
# Use snake_case
roles/technical_writer.pmd ✅
roles/TechnicalWriter.pmd ❌
roles/technical-writer.pmd ❌
Documentation
Document Variables
{# Senior Developer Role
Expected variables:
- primary_language: string - Main programming language
- years_experience: number - Years of experience (default: 10)
#}
You are a senior {{ primary_language }} developer...
Why: Clear variable documentation prevents confusion.
Add Context Comments
{# This checklist focuses on API security specifically,
not general application security.
Use with: API design prompts
Related: checklists/general_security.pmd
#}
Why: Helps others understand when and how to use the component.
Composition Best Practices
Include Paths
Use Relative Paths
# ✅ GOOD - Relative to current file
{% include "../components/roles/expert.pmd" %}
# ❌ BAD - Absolute path
{% include "/Users/username/project/roles/expert.pmd" %}
Why: Relative paths work across different environments.
Consistent Path Structure
prompts/
└── code_review.ymd → {% include "../components/roles/expert.pmd" %}
components/
└── roles/
└── expert.pmd
Why: Consistent structure makes includes predictable.
Composition Depth
Keep Reasonable Depth
# ✅ GOOD - 3 levels
main.ymd
└── profile.pmd
└── role.pmd
# ⚠️ ACCEPTABLE - 5 levels
main.ymd
└── orchestrator.pmd
└── profile.pmd
└── role.pmd
└── core.pmd
# ❌ BAD - 7+ levels (too deep)
main.ymd → ... → ... → ... → ... → ... → deep.pmd
Why: Deep nesting becomes hard to understand and debug.
Avoid Circular Dependencies
Bad Pattern
a.pmd includes b.pmd
b.pmd includes c.pmd
c.pmd includes a.pmd ❌ Circular!
Good Pattern
a.pmd includes shared.pmd
b.pmd includes shared.pmd
c.pmd includes shared.pmd ✅ No cycle
Why: Circular dependencies cause infinite loops.
Variable Best Practices
Naming
Use Descriptive Names
# ✅ GOOD
user_profile_data: {{ user_profile_data }}
max_retry_attempts: {{ max_retry_attempts }}
api_base_url: {{ api_base_url }}
# ❌ BAD
data: {{ data }}
max: {{ max }}
url: {{ url }}
Why: Clear names prevent confusion about variable purpose.
Documentation
Document in YMD
{# Expected variables:
- language: string - Programming language (e.g., "python", "javascript")
- code: string - Code to review
- strict_mode: boolean - Enable strict validation (default: false)
#}
Document in PMD
{# Expected variables:
- domain: string - Domain of expertise
- experience_level: string - "junior" | "senior" | "expert"
#}
Why: Clear documentation prevents runtime errors.
Defaults
Provide Sensible Defaults
{% set max_retries = max_retries | default(3) %}
{% set timeout = timeout | default(30) %}
Why: Makes variables optional when appropriate.
File Organization Best Practices
Directory Structure
Organize by Category
project/
├── prompts/ # YMD files
│ ├── code_review.ymd
│ └── api_design.ymd
│
└── components/ # PMD files
├── roles/
├── checklists/
├── formats/
└── shared/
Why: Clear structure improves discoverability.
Or by Domain
project/
├── prompts/
└── components/
├── python/ # Python-specific
├── javascript/ # JavaScript-specific
└── general/ # Language-agnostic
Why: Domain organization works well for specialized use cases.
File Placement
Place by Function
# Role definitions
components/roles/senior_dev.pmd
# Validation checklists
components/checklists/security.pmd
# Output formats
components/formats/json_response.pmd
# Shared content
components/shared/principles.pmd
Why: Function-based placement is intuitive.
Testing Best Practices
Validate Regularly
# After creating/editing files
/validate-composition path/to/file.ymd
Why: Catch errors early.
Test Include Chains
# Test that all includes resolve
# Test with sample variables
# Verify no circular dependencies
Why: Ensures composition works as expected.
Version Control
# Commit YMD and PMD files together
git add prompts/code_review.ymd
git add components/roles/senior_dev.pmd
git commit -m "Add code review prompt with senior dev role"
Why: Keeps related changes together.
Performance Best Practices
Minimize Include Depth
Recommendation: Keep depth ≤ 5 levels
Why: Deep nesting impacts render performance and debugging.
Reuse Components
# ✅ GOOD - Reuse across prompts
review_focus: |
{% include "checklists/quality.pmd" %}
# ❌ BAD - Duplicate content
review_focus: |
## Quality Checklist
[same content copied in multiple YMDs]
Why: Reuse reduces duplication and maintenance burden.
Cache Common Components
If using rendering library, cache frequently used PMDs.
Why: Reduces file I/O for repeated includes.
Maintenance Best Practices
Version Your Prompts
meta:
version: 1.0.0 # Track changes
# Document changes in CHANGELOG
Review Periodically
- Check for outdated components
- Remove unused PMDs
- Update variable documentation
- Refactor complex compositions
Keep Documentation Updated
- Update README when structure changes
- Document new patterns
- Keep examples current
Common Patterns
Pattern: Adapter
Create thin adapter YMDs for different use cases:
# code_review_strict.ymd
{% set strict_mode = true %}
{% include "code_review_base.ymd" %}
# code_review_relaxed.ymd
{% set strict_mode = false %}
{% include "code_review_base.ymd" %}
Pattern: Template Method
Base YMD with customization points:
# base.ymd
system: |
{% include "roles/base_role.pmd" %}
{% block custom_expertise %}{% endblock %}
Pattern: Composition
Build complex from simple:
system: |
{% include "roles/expert.pmd" %}
{% include "shared/principles.pmd" %}
{% include "shared/communication_style.pmd" %}
Anti-Patterns to Avoid
❌ Giant Monolithic PMD
<!-- DON'T: 500+ line PMD doing everything -->
Fix: Split by responsibility into multiple PMDs.
❌ Flat Metadata in YMD
# DON'T
id: example
kind: task
Fix: Group under meta:.
❌ Magic Values
# DON'T
if attempts > 3:
Fix: Use variables:
{% set max_attempts = max_attempts | default(3) %}
if attempts > max_attempts:
❌ No Variable Documentation
# DON'T: Undocumented variables
user: |
{{ mysterious_variable }}
Fix: Document all variables.
Checklist Before Publishing
- YMD has grouped
meta:section - PMD has NO
meta:section - All includes use relative paths
- All variables documented
- No circular dependencies
- Naming follows conventions
- Files validated with
/validate-composition - Tested with sample variables
- README updated (if needed)
Getting Help
- Use
@ymd-authorfor guided creation - Use
@composition-expertfor structure advice - Use
@ymd-validatorfor debugging - Check Examples for patterns
- Refer to Specifications for details