| file_type | documentation | ||||||||
|---|---|---|---|---|---|---|---|---|---|
| title | Frontmatter Schema Documentation | ||||||||
| version | v2.3 | ||||||||
| last_updated | 2026-06-03 | ||||||||
| author | LightSpeedWP | ||||||||
| maintainer | Ash Shaw | ||||||||
| description | Comprehensive documentation for the LightSpeedWP Markdown/JSON frontmatter schema, including GitHub templates, AI configurations, and validation guidelines. | ||||||||
| tags |
|
||||||||
| stability | stable | ||||||||
| domain | governance |
This document describes the structure, fields, and validation rules for the LightSpeedWP frontmatter schema, used across Markdown and JSON files for documentation, agents, prompts, and configuration.
- Ensure consistent metadata for all documentation, agent, and configuration files.
- Power automation, validation, and discoverability in the LightSpeedWP ecosystem.
- Support VS Code, Copilot, and other tools with a single source of truth.
- Schema file:
../schema/frontmatter.schema.json - This documentation:
docs/FRONTMATTER_SCHEMA.md
How to reference in documentation:
**JSON Schema:**
See [`../schema/frontmatter.schema.json`](../schema/frontmatter.schema.json)How to reference in frontmatter files (YAML):
$schema: "../schema/frontmatter.schema.json"
---
title: "..."The LightSpeedWP frontmatter schema uses Ajv JSON Schema validator (Draft 07) with a discriminator pattern for efficient validation routing.
- Parse YAML Frontmatter: Extract frontmatter block from Markdown files
- Load Schema: Read
../schema/frontmatter.schema.json - Discriminator Routing: Use
file_typefield to route to appropriate schema variant - Validate Fields: Check all required and optional fields against schema rules
- Report Errors: Provide detailed error messages with field paths and validation failures
The schema uses the file_type field as a discriminator to determine which validation rules apply:
{
"discriminator": {
"propertyName": "file_type"
},
"oneOf": [
{ "properties": { "file_type": { "const": "agent" } } },
{ "properties": { "file_type": { "const": "instructions" } } },
{ "properties": { "file_type": { "const": "prompt" } } },
{ "properties": { "file_type": { "const": "documentation" } } }
]
}This pattern ensures:
- Type Safety: Each file type has specific required fields
- Performance: Fast validation routing without checking all variants
- Clarity: Clear error messages specific to each file type
- Extensibility: Easy to add new file types without breaking existing validation
| Field | Type | Required | Description |
|---|---|---|---|
| title | string | yes | Human-readable title |
| description | string | yes | Brief summary of the file's purpose |
| version | string | yes | Schema or document version (e.g. v1.0) |
| last_updated | string | yes | ISO date of last update |
| author | string | yes | Main author or team |
| maintainer | string | yes | Who's responsible for changes |
| tags | string[] | no | Keywords for search/filtering |
| type | string | yes | Type of file (e.g. "agent", "instructions") |
| references | string[] | no | AI-relevant cross-links for automation and discovery |
The LightSpeedWP frontmatter schema implements a dual reference system to serve both AI automation and human navigation needs:
- Location:
referencesfield in YAML frontmatter - Purpose: Machine-readable cross-links for AI agents, automation, and discovery
- Audience: GitHub Copilot, automation agents, search indexing
- Format: Relative paths to related files that AI should understand
- Location: Reference section at the end of the document
- Purpose: Human-readable navigation links with context
- Audience: Developers, contributors, documentation readers
- Format: Markdown links with descriptions and context
$schema: "../schema/frontmatter.schema.json"
---
title: "Labeling Agent Spec"
description: "Automated labeling system for issues and pull requests"
version: "v1.2"
last_updated: "2025-10-24"
author: "LightSpeedWP"
maintainer: "Ash Shaw"
tags: ["lightspeed", "labeling", "agents", "automation"]
type: "agent"
references:
- "../workflows/labeling.yml"
- "../prompts/label-issues.prompt.md"
- "../instructions/automation.instructions.md"
- "./LABELING.md"
- "./LABELING.md#issue-labelling"
- "./LABELING.md#pull-request-labelling"
---
# 🏷️ Labeling Agent Specification
[Document content here...]
## 🔗 Related Documentation
- **[Labeling Workflow](../.github/workflows/labeling.yml)** - GitHub Actions implementation
- **[Issue Labels](./LABELING.md#issue-labelling)** - Complete labeling taxonomy
- **[PR Labels](./LABELING.md#pull-request-labelling)** - Pull request labeling standards
---
*This agent specification ensures consistent issue and PR labeling across the LightSpeedWP organization.*-
AI References should include:
- Related workflow files
- Dependent instruction files
- Associated prompt files
- Configuration files
- Schema files
-
Human References should include:
- Contextual descriptions
- Navigation aids
- Related documentation
- External resources
- Explanatory links
references:
- "../workflows/agent-name.yml"
- "../prompts/agent-prompt.prompt.md"
- "./agents.instructions.md"
- "./LABELING.md#issue-labelling"references:
- "./coding-standards.instructions.md"
- "../workflows/README.md"
- "../agents/README.md"
- "../custom-instructions.md"references:
- "../instructions/prompts.instructions.md"
- "../agents/agent.md"
- "../agents/agent-name.agent.md"references:
- "../agents/agent-name.agent.md"
- "../instructions/workflows.instructions.md"
- "./AUTOMATION.md"Use descriptive markdown links that help humans understand context:
## 🔗 Related Documentation
### 📚 Core Resources
- **[Automation Governance](./AUTOMATION.md)** - Organization automation policies
- **[Coding Standards](./instructions/coding-standards.instructions.md)** - Development guidelines
### ⚙️ Implementation Details
- **[Labeling Workflow](../workflows/labeling.yml)** - GitHub Actions automation
- **[Test Configuration](../jest.config.js)** - Testing framework setup
### 🎯 Specialized Guides
- **[WordPress Development](./instructions/wordpress.instructions.md)** - WP-specific practices
- **[Security Guidelines](./instructions/security.instructions.md)** - Security best practicesGitHub issue templates use YAML frontmatter for the new Issue Forms feature to define metadata and form fields. All issue form files must begin with at least three keys: name, description, and body.
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | ✅ | Unique name for the template (appears in template picker UI) |
description |
string | ✅ | Short explanation of the template's purpose (shown in picker UI) |
body |
array | ✅ | Array defining the form fields and content blocks for the issue form |
title |
string | 📋 | Default title that will pre-fill in the new issue title input |
labels |
array/string | 📋 | Labels to auto-apply on issue creation (array or comma-separated) |
assignees |
array/string | 📋 | GitHub usernames to auto-assign the issue to (array or comma-separated) |
projects |
array/string | 📋 | GitHub Projects to auto-add the issue to (format "OWNER/PROJECT-NUMBER") |
type |
string | 📋 | Issue type to assign (if your organization uses custom issue types) |
---
name: "Bug Report"
description: "Report a bug in the project."
title: "[Bug]: "
labels: ["bug", "needs-triage"]
assignees: ["octocat"]
projects: ["my-org/42"]
type: bug
body:
- type: markdown
attributes:
value: |
## Thank you for reporting a bug!
Please fill out the sections below.
- type: input
id: "contact"
attributes:
label: "Contact Details"
placeholder: "e.g. email@example.com"
validations:
required: false
- type: textarea
id: "steps"
attributes:
label: "Steps to Reproduce"
placeholder: |
1. Step one...
2. Step two...
3. *Feel free to add more steps as needed...*
validations:
required: true
- type: dropdown
id: "browser"
attributes:
label: "Affected Browser(s)"
options:
- "Firefox"
- "Chrome"
- "Safari"
- "Edge"
multiple: true
validations:
required: true
- type: checkboxes
id: "agree"
attributes:
label: "Code of Conduct Agreement"
options:
- label: "I have searched for duplicate issues"
required: true
- label: "I agree to follow the project's Code of Conduct"
required: true
---The body array supports these input types:
markdown— Static text guidance (not included in final issue content)input— Single-line text field withlabel,description,placeholder,value, andvalidationstextarea— Multi-line text field, supportsrenderto format as code blockdropdown— Single or multi-select from options list, supportsmultiple: trueanddefaultindexcheckboxes— Group of checkboxes, each withlabeland optionalrequired: true
- Enclose frontmatter between
---lines at the top of the template file - Quote strings containing special characters (
:,#) or beginning with[ - Use pipe
|for multiline text to preserve line breaks - Use
validations: required: truejudiciously — only when necessary - Assign unique IDs to inputs for programmatic reference
- Keep forms short — only ask for necessary information
Pull request templates are simpler — GitHub does not currently support form-style PR templates with YAML-defined inputs. Issue forms are for issues only.
You can include YAML frontmatter at the top of a PR template, but GitHub ignores these fields for PRs. Any frontmatter will simply remain as visible text in the PR body.
---
name: "Feature PR Template"
about: "Use this template for pull requests adding a new feature"
title: "feat: <brief description of feature>"
labels: enhancement, needs-review
assignees: octocat
---- Use HTML comments (
<!-- ... -->) for guidance text - Encourage linking issues (e.g., "Closes #123")
- Include sections for "Linked Issue", "Summary of Changes", "Testing Instructions"
- Use Markdown checklists for reviewer guidance
GitHub saved replies are canned responses for commenting on issues and PRs. They do not use file-based YAML frontmatter — they are created and managed via the GitHub web UI.
Each saved reply has:
- Title — Short name for the reply (for your reference in the UI)
- Body content — The actual text (supports Markdown) inserted when used
Usage: Create/edit via Settings > Saved replies. Only the body content gets inserted into comments.
Create a file named .github/copilot-instructions.md at the repository root. This file contains plain Markdown guidance for Copilot — no YAML frontmatter needed.
Example:
# Project Coding Guidelines
- Follow WordPress Coding Standards for PHP, JavaScript, and CSS
- Use semantic HTML and ensure accessibility (WCAG 2.2 AA)
- All code must pass ESLint, PHPCS, and Prettier formatting
- Include comprehensive JSDoc and PHPDoc for all functionsCreate files in .github/instructions/ with names like XYZ.instructions.md. These require YAML frontmatter with applyTo patterns.
| Field | Type | Required | Description |
|---|---|---|---|
applyTo |
string/array | ✅ | Glob pattern(s) of files this applies to |
description |
string | 📋 | Short description (shown in VS Code UI) |
Example:
---
applyTo: "**/*.py"
description: "Python code style guidelines for this repo"
---
# Python Coding Guidelines
- Follow PEP 8 style guide (use `black` for formatting)
- Use type hints for all functions and methods
- Prefer list comprehensions for simple loops
- Avoid wildcard `import` statementsBest Practices:
- Keep instructions concise and natural language
- Use separate files for distinct domains (language, testing, deployment)
- Name files logically (e.g.,
python.instructions.md,frontend.instructions.md) - Use precise
applyToglob patterns
Prompt files define reusable prompts for VS Code Copilot Chat with YAML frontmatter.
| Field | Type | Required | Description |
|---|---|---|---|
description |
string | ✅ | Short description of what the prompt does |
mode |
enum | 📋 | Execution mode: "ask", "edit", or "agent" (default: agent) |
model |
string | 📋 | Preferred AI model (e.g., "gpt-4", "claude-3") |
tools |
array | 📋 | List of tools/capabilities the prompt can use |
Example:
---
description: "Convert a code snippet into a well-documented function"
mode: "edit"
model: "GPT-4"
tools: []
---
# Convert to Documented Function
Take the selected code and refactor it into a self-contained function with a clear name.
- Add a concise docstring explaining purpose, inputs, and output
- Add comments for complex logic
- **Do not** change external behaviorVariables: Use placeholders like ${selection}, ${file}, or ${input:variableName} in prompt body.
.chatmode.md files in favor of .agent.md files. All chatmode references should be migrated to agent format.
Agent files define specialized AI modes for Copilot Chat. Structure mirrors prompt files with expanded capabilities.
| Field | Type | Required | Description |
| -------------- | ------ | -------- | ------------------------------------------ | ------------------ | ------------ |
| name | string | ✅ | Human-readable agent name (VS Code native) |
| description | string | ✅ | Brief description of agent purpose |
| tools | array | 📋 | Available tools/capabilities |
| model | string | 📋 | Preferred AI model |
| handoffs | array | 📋 | Handoff definitions for agent chaining |
| version | string | 📋 | Version string (LightSpeed extended) |
| last_updated | string | 📋 | ISO date |
| owners | array | 📋 | Responsible teams |
| category | string | 📋 | Classification |
| status | string | 📋 | "active" | "deprecated" | "draft" |
| target | string | 📋 | "vscode" | "github-copilot" | "cli" |
| visibility | string | 📋 | "public" | "private" | "internal" |
| metadata | object | 📋 | Additional agent metadata |
Example:
---
name: "security-reviewer"
description: "Security vulnerability assessment and remediation guidance"
tools: ["search", "codebase", "problems"]
model: "gpt-4"
handoffs:
- label: "Fix Issues"
agent: "implementation"
prompt: "Now implement the security fixes identified above."
send: false
version: "v1.0"
last_updated: "2025-12-04"
owners: ["lightspeedwp/security-team"]
category: "security"
status: "active"
target: "vscode"
visibility: "public"
---
# Security Reviewer Agent
You are a security expert focusing on WordPress vulnerabilities...Agent Tools: Values include codebase, search, usages, editFiles, fetchWebpage, findTestFiles, githubRepo, problems, runCommands, runNotebooks, runTasks, runTests, terminalLastCommand, terminalSelection, thinking, vscodeAPI, and custom MCP tools.
The AGENTS.md file at repository root provides guidelines for all AI assistants working on the repository. This convention unifies rules across GitHub Copilot, Claude, Gemini, and other AI tools.
AGENTS.md is plain Markdown — no YAML frontmatter required. Content should be universal rules applicable to any AI assistant.
Example:
# Project AI Guidelines
- All code must follow the style guide in [CONTRIBUTING.md](CONTRIBUTING.md)
- Assume users are familiar with the project domain
- Prioritize security and privacy — never output secrets
- Every generated function _must_ have a docstring
- Follow OWASP security best practices- Broad Application: Rules apply to all AI actions in the repo
- Static Guidelines: Should be relatively stable and universal
- Cross-Platform: Works with GitHub Copilot, Claude, Gemini, Continue.dev, etc.
- Keep high-level (project-wide concerns only)
- Avoid granular/context-specific rules (use
.instructions.mdfor those) - Update as project practices evolve
- Single source of truth for AI behavior
The LightSpeedWP frontmatter schema uses Ajv JSON Schema validator with a discriminator pattern on the file_type field for routing validation rules.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"discriminator": {
"propertyName": "file_type"
},
"oneOf": [
{ "properties": { "file_type": { "const": "agent" } } },
{ "properties": { "file_type": { "const": "instructions" } } },
{ "properties": { "file_type": { "const": "prompt" } } }
]
}The file_type field determines which validation rules apply to each file.
- Parse YAML frontmatter from Markdown files
- Extract
file_typefield to determine schema variant - Route to appropriate schema using discriminator
- Validate all fields against schema requirements
- Report errors with file path and field details
| Error | Cause | Solution |
|---|---|---|
| "Missing required field" | Required field omitted | Add missing field to frontmatter |
| "Invalid file_type" | Typo or unsupported type | Check spelling, use valid type |
| "Duplicate property" | Same field appears twice | Remove duplicate (common: file_type) |
| "Invalid enum value" | Field value not in allowed list | Use valid enum value from schema |
| "Type mismatch" | Wrong data type | Convert to correct type (e.g., string vs array) |
Configure VS Code to validate frontmatter in real-time:
.vscode/settings.json:
{
"yaml.schemas": {
"../schema/frontmatter.schema.json": [".github/**/*.md", "docs/**/*.md"]
},
"yaml.validate": true,
"yaml.format.enable": true
}Benefits:
- Real-time validation as you type
- IntelliSense autocomplete for fields
- Inline error messages
- Quick fixes for common issues
Automated validation in GitHub Actions:
.github/workflows/validate-frontmatter.yml:
name: Validate Frontmatter
on:
pull_request:
paths:
- "**.md"
- "../schema/frontmatter.schema.json"
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
- run: npm ci
- run: npm run validate:frontmatterValidation Script (scripts/validation/validate-frontmatter.js):
const Ajv = require("ajv");
const yaml = require("js-yaml");
const fs = require("fs");
const glob = require("glob");
const ajv = new Ajv({ discriminator: true, allErrors: true });
const schema = JSON.parse(
fs.readFileSync("../schema/frontmatter.schema.json", "utf8"),
);
const validate = ajv.compile(schema);
const files = glob.sync(".github/**/*.md");
let errors = 0;
files.forEach((file) => {
const content = fs.readFileSync(file, "utf8");
const match = content.match(/^---\n([\s\S]+?)\n---/);
if (match) {
try {
const frontmatter = yaml.load(match[1]);
const valid = validate(frontmatter);
if (!valid) {
console.error(`\nValidation errors in ${file}:`);
validate.errors.forEach((err) => {
console.error(` - ${err.instancePath}: ${err.message}`);
});
errors++;
}
} catch (e) {
console.error(`\nYAML parse error in ${file}:`, e.message);
errors++;
}
}
});
if (errors > 0) {
console.error(`\n❌ Validation failed: ${errors} file(s) with errors`);
process.exit(1);
} else {
console.log("\n✅ All frontmatter is valid");
}Validate before committing with Husky:
.husky/pre-commit:
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npm run validate:frontmatterpackage.json:
{
"scripts": {
"validate:frontmatter": "node scripts/validation/validate-frontmatter.js"
}
}| Field | Type | Required | Description |
|---|---|---|---|
file_type |
string | ✅ | Discriminator for schema validation (const per file type) |
description |
string | ✅ | Human-readable summary (single sentence preferred) |
title |
string | ✅* | Human-readable title (required for governance files) |
version |
string | ✅* | Version string (e.g., v1.1) for governance tracking |
last_updated |
string | ✅* | ISO date of last update (YYYY-MM-DD format) |
author |
string | 📋 | Main author or responsible party |
maintainer |
string | 📋 | Current maintainer |
owners |
array[string] | 📋 | List of owners/maintainers (alternative to maintainer) |
| Field | Type | Description |
|---|---|---|
mode |
enum | Execution style: agent, ask, edit |
applyTo |
string/array | Glob patterns for auto-application scope |
model |
string | Preferred AI model (e.g., "gpt-4", "claude-3") |
tools |
array[string] | Available tools/capabilities |
permissions |
array[string] | Declared permission scopes (read/write/edit, shell, GitHub subsets) |
deprecated |
boolean | Signals exclusion from generated tables |
replacement |
string | Points to canonical successor file |
stability |
enum | Maturity: stable, experimental, incubating |
tags |
array[string] | Taxonomy for discovery/filtering (max 8) |
domain |
enum | Primary classification |
extraDomains |
array[string] | Secondary classifications |
license |
string | License identifier (e.g., "GPL-3.0", "MIT") |
references |
array[object] | AI-focused references with path and description |
Primary Domains (choose exactly one for domain):
wp-core— WordPress core functionality, hooks, APIsblock-theme— Block themes, FSE, theme.json, patternsplugin-hardening— Plugin security, validation, best practicesperf— Performance optimization, caching, speeda11y— Accessibility, WCAG compliance, inclusive designi18n— Internationalization, localization, translationssecurity— Security hardening, sanitization, authenticationheadless— Headless WordPress, APIs, decoupled architecturegeneric— General purpose, cross-domain, or unclassified
Supplemental Tags (use in tags array, max 8 total):
- Development:
testing,lint,ci,automation,docs,validation - WordPress:
rest,graphql,gutenberg,blocks,patterns,theme-json - Technical:
api,data,editor,cli,deployment,logging - UX/Design:
ux,design-tokens,accessibility,responsive,mobile
- Limit: Max 8 tags total for clarity and performance
- Format: Use lowercase kebab-case only (no spaces, no uppercase)
- No Duplication: Don't repeat
domainintags(it's implicit) - Consistency: Prefer existing tags; only create new ones with clear reuse potential
- Specificity: Be specific enough for discovery, general enough for reuse
| Stability | Intent | Change Expectations |
|---|---|---|
experimental |
Early exploration | Breaking changes likely |
incubating |
Maturing, seeking feedback | Minor structural tweaks possible |
stable |
Adopted, versioned conventions | Backward compatibility strongly preferred |
- Add
file_typefield — Required for schema discrimination - Update field names — Change
apply_to→applyTofor instructions - Add governance fields — Include
version,last_updated,authorfor docs - Select domain — Choose primary domain from approved taxonomy
- Limit tags — Reduce to 8 or fewer, use kebab-case
- Add references — Include AI-focused cross-links in frontmatter
| Issue | Fix |
|---|---|
Duplicate file_type |
Remove second instance |
| Missing required fields | Add description, file_type |
| Invalid domain | Use approved domain from taxonomy |
| Too many tags | Reduce to 8, remove redundant ones |
| Uppercase tags | Convert to lowercase kebab-case |
| Old field names | Update apply_to → applyTo |