Skill for iteratively improving SKILL.md frontmatter compliance using the Ralph loop pattern
58
stars
65
commits
TypeScript
primary language
Jun 1, 2026
updated
"A true master teaches not by telling, but by refining." - The Skill Sensei
Sensei automates the improvement of Agent Skills frontmatter compliance using the Ralph loop pattern - iteratively improving skills until they reach Medium-High compliance with all tests passing.
Skills without proper frontmatter lead to skill collision - agents invoking the wrong skill for a given prompt. Common issues include:
Sensei implements the "Ralph Wiggum" technique:
Run sensei on my-skill-name
Run sensei on my-skill-name --fast
Run sensei on skill-a, skill-b, skill-c
Run sensei on all Low-adherence skills
Run sensei on all skills
Run sensei on my-skill-name --gepa
Run sensei score my-skill-name
Score-only mode runs without LLM calls.
npx @spboyer/sensei score .
npx @spboyer/sensei check --root . --config .token-limits.json --strict
--root resolves paths; --config selects limits; --emit-proof writes sensei-audit.md; .sensei.json enables repo policy. Install globally via npm i -g @spboyer/sensei.
steps:
- uses: actions/checkout@v4
- uses: spboyer/sensei@v1.5.0
with:
command: check
root: .
path: .
config: .token-limits.json
strict: 'true'
import { scoreSkillContent } from '@spboyer/sensei/score';
import { parseFrontmatter } from '@spboyer/sensei/parse';
import { checkNameCompliance } from '@spboyer/sensei/checks';
const result = scoreSkillContent(renderedSkillMarkdown, { path: 'skills/my-skill', moduleCount: 2 });
const frontmatter = parseFrontmatter(renderedSkillMarkdown);
checkNameCompliance(frontmatter?.name ?? '');
path is metadata; moduleCount defaults to 0.
python scripts/src/gepa/auto_evaluator.py score --skill my-skill
python scripts/src/gepa/auto_evaluator.py optimize --skill my-skill
| Flag | Description |
|---|---|
--fast | Skip tests for faster iteration |
--gepa | Use GEPA evolutionary optimization instead of template-based improvements |
--skip-integration | Skip integration tests (unit + trigger tests only) |
⚠️ Note: Using
--fastspeeds up the loop significantly but may miss issues. Consider running full tests before final commit.
Node.js 18+ - For running token management scripts
node --version
Git - For commits and comparisons
git --version
Test Framework - Jest, pytest, or similar for trigger tests
Python 3.10+ and GEPA - For evolutionary optimization (pip install gepa)
mkdir -p "$HOME/.copilot/skills"
git clone https://github.com/spboyer/sensei.git "$HOME/.copilot/skills/sensei"
cd ~/.copilot/skills/sensei/scripts && npm install
The skill is now available in Copilot CLI. Invoke with:
Run sensei on my-skill-name
For project-specific installation:
mkdir -p .github/skills
git clone https://github.com/spboyer/sensei.git .github/skills/sensei
cd .github/skills/sensei/scripts && npm install
For CLI/library use:
npm install --global @spboyer/sensei
sensei check .
npx @spboyer/sensei check .
cd ~/.copilot/skills/sensei && npm run tokens -- check
npx @spboyer/sensei check .
┌─────────────────────────────────────────────────────────┐
│ START: User invokes "Run sensei on {skill-name}" │
└─────────────────────┬───────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────┐
│ 1. READ: Load skills/{skill-name}/SKILL.md │
│ Load tests/{skill-name}/ (if exists) │
│ Count tokens (baseline for comparison) │
└─────────────────────┬───────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────┐
│ 2. SCORE: Run rule-based compliance check │
│ • Check description length (> 150 chars?) │
│ • Check for trigger phrases ("USE FOR:") │
│ • Check for anti-triggers ("DO NOT USE FOR:") │
│ • Check for compatibility field │
└─────────────────────┬───────────────────────────────────┘
▼
┌───────────────┐
│ Score >= M-H │──YES──▶ COMPLETE ✓
│ AND tests pass│ (next skill)
└───────┬───────┘
│ NO
▼
┌─────────────────────────────────────────────────────────┐
│ 3. SCAFFOLD: If tests/{skill-name}/ missing: │
│ Create tests from references/test-templates/ │
│ Creates prompts.md and framework-specific tests │
└─────────────────────┬───────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────┐
│ 4. IMPROVE FRONTMATTER: │
│ • Add "USE FOR:" with trigger phrases │
│ • Add "DO NOT USE FOR:" with anti-triggers │
│ • Add compatibility if applicable │
│ • Keep description under 1024 chars │
│ • OR with --gepa: GEPA evolutionary optimization │
└─────────────────────┬───────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────┐
│ 5. IMPROVE TESTS: │
│ • Update shouldTriggerPrompts (5+ prompts) │
│ • Update shouldNotTriggerPrompts (5+ prompts) │
│ • Match prompts to new frontmatter triggers │
└─────────────────────┬───────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────┐
│ 6. VERIFY: Run tests for the skill │
│ • If tests fail → fix and retry │
│ • If tests pass → continue │
└─────────────────────┬───────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────┐
│ 7. CHECK TOKENS: │
│ npm run tokens count {skill}/SKILL.md │
│ Verify under 500 token soft limit │
└─────────────────────┬───────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────┐
│ 8. SUMMARY: Display before/after comparison │
│ • Score change (Low → Medium-High) │
│ • Token delta (+/- tokens) │
│ • Unimplemented suggestions │
└─────────────────────┬───────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────┐
│ 9. PROMPT USER: Choose action │
│ [C] Commit changes │
│ [I] Create GitHub issue with suggestions │
│ [S] Skip (discard changes) │
└─────────────────────┬───────────────────────────────────┘
▼
┌───────────────┐
│ Iteration < 5 │──YES──▶ Go to step 2
└───────┬───────┘
│ NO
▼
TIMEOUT (move to next skill)
When running on multiple skills:
| Setting | Default | Description |
|---|---|---|
| Skills directory | skills/ or .github/skills/ | Where SKILL.md files live |
| Tests directory | tests/ | Where test files live |
| Max iterations | 5 | Per-skill iteration limit before moving on |
| Target score | Medium-High | Minimum compliance level |
| Token soft limit | 500 | SKILL.md target token count |
| Token hard limit | 5000 | SKILL.md maximum token count |
| User prompt | After each skill | Commit, Create Issue, or Skip |
| Continue on failure | Yes | Process remaining skills if one fails |
Override defaults in your prompt:
Run sensei on my-skill with skills in src/ai/skills/ and tests in spec/
| Level | Description | Criteria |
|---|---|---|
| Low | Basic description | No explicit triggers, often < 150 chars |
| Medium | Has trigger keywords | Description > 150 chars, implicit or explicit trigger phrases, >60 words |
| Medium-High | Has WHEN: or USE FOR: | "WHEN:" (preferred) or "USE FOR:" with ≤60 words |
| High | Full compliance | Medium-High + routing clarity (INVOKES/FOR SINGLE OPERATIONS) |
Name validation
Description length
Trigger phrases
Anti-triggers (optional, context-dependent)
Routing clarity (for High score)
**WORKFLOW SKILL**, **UTILITY SKILL**, or **ANALYSIS SKILL**INVOKES: lists tools/MCP servers the skill callsFOR SINGLE OPERATIONS: guidance for when to bypass skillTo reach Medium-High, a skill must have:
To reach High, add routing clarity:
**WORKFLOW SKILL**, etc.)INVOKES: listing tools/MCP servers usedFOR SINGLE OPERATIONS: bypass guidanceWhen a skill's description contains INVOKES:, Sensei performs additional checks based on the MCP Integration Patterns:
| Check | Purpose |
|---|---|
| MCP Tools Used table | Documents tool dependencies in skill body |
| Prerequisites section | Lists required tools and permissions |
| CLI fallback pattern | Provides fallback when MCP unavailable |
| Name collision detection | Warns when skill name matches MCP tool |
MCP Integration Score (0-4 points):
See references/mcp-integration.md for detailed patterns.
npm run tokens -- score [dir]npm run tokens -- checknpm run tokens -- suggest---
name: pdf-processor
description: 'Process PDF files for various tasks'
---
Problems:
---
name: pdf-processor
description: "Extract, rotate, merge, and split PDF files. WHEN: \"extract PDF text\", \"rotate PDF pages\", \"merge PDFs\", \"split PDF\", \"PDF to text\"."
---
Improvements:
---
name: azure-deploy
description: |
**WORKFLOW SKILL** - Orchestrates deployment through preparation, validation,
and execution phases for Azure applications.
USE FOR: "deploy to Azure", "azd up", "push to Azure", "publish to Azure".
DO NOT USE FOR: preparing new apps (use azure-prepare), validating before
deploy (use azure-validate), Azure Functions specifically (use azure-functions).
INVOKES: azure-azd MCP (up, deploy, provision), azure-deploy MCP (plan_get).
FOR SINGLE OPERATIONS: Use azure-azd MCP directly for single azd commands.
---
High score achieved with:
**WORKFLOW SKILL**)INVOKES: lists MCP tools usedFOR SINGLE OPERATIONS: guides when to bypass skillBefore (empty):
const shouldTriggerPrompts = [];
const shouldNotTriggerPrompts = [];
After:
const shouldTriggerPrompts = [
'Extract text from this PDF',
'Rotate this PDF 90 degrees',
'Merge these PDF files together',
'Split this PDF into pages',
'Convert PDF to text',
];
const shouldNotTriggerPrompts = [
'Create a new PDF document',
'Extract images from this PDF',
'OCR this scanned document',
'What is the weather today?',
'Help me with AWS S3',
];
Ensure shouldTriggerPrompts match "USE FOR:" phrases and shouldNotTriggerPrompts match "DO NOT USE FOR:" scenarios.
Common causes: description > 1024 chars, anti-triggers not using "DO NOT USE FOR:" format, or conflicting triggers with other skills.
git reset --soft HEAD~1 # Undo last commit
SKILL.md for instruction changesreferences/*.md for documentation changesnpm run tokens -- checkreferences/scoring.mdreferences/examples.mdreferences/test-templates/{framework}.mdSensei supports Waza-style trigger accuracy testing. See the Waza test template.
Open an issue with skill name, starting state, and git log --oneline -10.
Sensei - "The path to compliance begins with a single trigger." 🥋
TypeScript
74.0%
Python
17.2%
JavaScript
5.7%
Shell
3.0%
Skill for iteratively improving SKILL.md frontmatter compliance using the Ralph loop pattern
58
stars
65
commits
TypeScript
primary language
Jun 1, 2026
updated
"A true master teaches not by telling, but by refining." - The Skill Sensei
Sensei automates the improvement of Agent Skills frontmatter compliance using the Ralph loop pattern - iteratively improving skills until they reach Medium-High compliance with all tests passing.
Skills without proper frontmatter lead to skill collision - agents invoking the wrong skill for a given prompt. Common issues include:
Sensei implements the "Ralph Wiggum" technique:
Run sensei on my-skill-name
Run sensei on my-skill-name --fast
Run sensei on skill-a, skill-b, skill-c
Run sensei on all Low-adherence skills
Run sensei on all skills
Run sensei on my-skill-name --gepa
Run sensei score my-skill-name
Score-only mode runs without LLM calls.
npx @spboyer/sensei score .
npx @spboyer/sensei check --root . --config .token-limits.json --strict
--root resolves paths; --config selects limits; --emit-proof writes sensei-audit.md; .sensei.json enables repo policy. Install globally via npm i -g @spboyer/sensei.
steps:
- uses: actions/checkout@v4
- uses: spboyer/sensei@v1.5.0
with:
command: check
root: .
path: .
config: .token-limits.json
strict: 'true'
import { scoreSkillContent } from '@spboyer/sensei/score';
import { parseFrontmatter } from '@spboyer/sensei/parse';
import { checkNameCompliance } from '@spboyer/sensei/checks';
const result = scoreSkillContent(renderedSkillMarkdown, { path: 'skills/my-skill', moduleCount: 2 });
const frontmatter = parseFrontmatter(renderedSkillMarkdown);
checkNameCompliance(frontmatter?.name ?? '');
path is metadata; moduleCount defaults to 0.
python scripts/src/gepa/auto_evaluator.py score --skill my-skill
python scripts/src/gepa/auto_evaluator.py optimize --skill my-skill
| Flag | Description |
|---|---|
--fast | Skip tests for faster iteration |
--gepa | Use GEPA evolutionary optimization instead of template-based improvements |
--skip-integration | Skip integration tests (unit + trigger tests only) |
⚠️ Note: Using
--fastspeeds up the loop significantly but may miss issues. Consider running full tests before final commit.
Node.js 18+ - For running token management scripts
node --version
Git - For commits and comparisons
git --version
Test Framework - Jest, pytest, or similar for trigger tests
Python 3.10+ and GEPA - For evolutionary optimization (pip install gepa)
mkdir -p "$HOME/.copilot/skills"
git clone https://github.com/spboyer/sensei.git "$HOME/.copilot/skills/sensei"
cd ~/.copilot/skills/sensei/scripts && npm install
The skill is now available in Copilot CLI. Invoke with:
Run sensei on my-skill-name
For project-specific installation:
mkdir -p .github/skills
git clone https://github.com/spboyer/sensei.git .github/skills/sensei
cd .github/skills/sensei/scripts && npm install
For CLI/library use:
npm install --global @spboyer/sensei
sensei check .
npx @spboyer/sensei check .
cd ~/.copilot/skills/sensei && npm run tokens -- check
npx @spboyer/sensei check .
┌─────────────────────────────────────────────────────────┐
│ START: User invokes "Run sensei on {skill-name}" │
└─────────────────────┬───────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────┐
│ 1. READ: Load skills/{skill-name}/SKILL.md │
│ Load tests/{skill-name}/ (if exists) │
│ Count tokens (baseline for comparison) │
└─────────────────────┬───────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────┐
│ 2. SCORE: Run rule-based compliance check │
│ • Check description length (> 150 chars?) │
│ • Check for trigger phrases ("USE FOR:") │
│ • Check for anti-triggers ("DO NOT USE FOR:") │
│ • Check for compatibility field │
└─────────────────────┬───────────────────────────────────┘
▼
┌───────────────┐
│ Score >= M-H │──YES──▶ COMPLETE ✓
│ AND tests pass│ (next skill)
└───────┬───────┘
│ NO
▼
┌─────────────────────────────────────────────────────────┐
│ 3. SCAFFOLD: If tests/{skill-name}/ missing: │
│ Create tests from references/test-templates/ │
│ Creates prompts.md and framework-specific tests │
└─────────────────────┬───────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────┐
│ 4. IMPROVE FRONTMATTER: │
│ • Add "USE FOR:" with trigger phrases │
│ • Add "DO NOT USE FOR:" with anti-triggers │
│ • Add compatibility if applicable │
│ • Keep description under 1024 chars │
│ • OR with --gepa: GEPA evolutionary optimization │
└─────────────────────┬───────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────┐
│ 5. IMPROVE TESTS: │
│ • Update shouldTriggerPrompts (5+ prompts) │
│ • Update shouldNotTriggerPrompts (5+ prompts) │
│ • Match prompts to new frontmatter triggers │
└─────────────────────┬───────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────┐
│ 6. VERIFY: Run tests for the skill │
│ • If tests fail → fix and retry │
│ • If tests pass → continue │
└─────────────────────┬───────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────┐
│ 7. CHECK TOKENS: │
│ npm run tokens count {skill}/SKILL.md │
│ Verify under 500 token soft limit │
└─────────────────────┬───────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────┐
│ 8. SUMMARY: Display before/after comparison │
│ • Score change (Low → Medium-High) │
│ • Token delta (+/- tokens) │
│ • Unimplemented suggestions │
└─────────────────────┬───────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────┐
│ 9. PROMPT USER: Choose action │
│ [C] Commit changes │
│ [I] Create GitHub issue with suggestions │
│ [S] Skip (discard changes) │
└─────────────────────┬───────────────────────────────────┘
▼
┌───────────────┐
│ Iteration < 5 │──YES──▶ Go to step 2
└───────┬───────┘
│ NO
▼
TIMEOUT (move to next skill)
When running on multiple skills:
| Setting | Default | Description |
|---|---|---|
| Skills directory | skills/ or .github/skills/ | Where SKILL.md files live |
| Tests directory | tests/ | Where test files live |
| Max iterations | 5 | Per-skill iteration limit before moving on |
| Target score | Medium-High | Minimum compliance level |
| Token soft limit | 500 | SKILL.md target token count |
| Token hard limit | 5000 | SKILL.md maximum token count |
| User prompt | After each skill | Commit, Create Issue, or Skip |
| Continue on failure | Yes | Process remaining skills if one fails |
Override defaults in your prompt:
Run sensei on my-skill with skills in src/ai/skills/ and tests in spec/
| Level | Description | Criteria |
|---|---|---|
| Low | Basic description | No explicit triggers, often < 150 chars |
| Medium | Has trigger keywords | Description > 150 chars, implicit or explicit trigger phrases, >60 words |
| Medium-High | Has WHEN: or USE FOR: | "WHEN:" (preferred) or "USE FOR:" with ≤60 words |
| High | Full compliance | Medium-High + routing clarity (INVOKES/FOR SINGLE OPERATIONS) |
Name validation
Description length
Trigger phrases
Anti-triggers (optional, context-dependent)
Routing clarity (for High score)
**WORKFLOW SKILL**, **UTILITY SKILL**, or **ANALYSIS SKILL**INVOKES: lists tools/MCP servers the skill callsFOR SINGLE OPERATIONS: guidance for when to bypass skillTo reach Medium-High, a skill must have:
To reach High, add routing clarity:
**WORKFLOW SKILL**, etc.)INVOKES: listing tools/MCP servers usedFOR SINGLE OPERATIONS: bypass guidanceWhen a skill's description contains INVOKES:, Sensei performs additional checks based on the MCP Integration Patterns:
| Check | Purpose |
|---|---|
| MCP Tools Used table | Documents tool dependencies in skill body |
| Prerequisites section | Lists required tools and permissions |
| CLI fallback pattern | Provides fallback when MCP unavailable |
| Name collision detection | Warns when skill name matches MCP tool |
MCP Integration Score (0-4 points):
See references/mcp-integration.md for detailed patterns.
npm run tokens -- score [dir]npm run tokens -- checknpm run tokens -- suggest---
name: pdf-processor
description: 'Process PDF files for various tasks'
---
Problems:
---
name: pdf-processor
description: "Extract, rotate, merge, and split PDF files. WHEN: \"extract PDF text\", \"rotate PDF pages\", \"merge PDFs\", \"split PDF\", \"PDF to text\"."
---
Improvements:
---
name: azure-deploy
description: |
**WORKFLOW SKILL** - Orchestrates deployment through preparation, validation,
and execution phases for Azure applications.
USE FOR: "deploy to Azure", "azd up", "push to Azure", "publish to Azure".
DO NOT USE FOR: preparing new apps (use azure-prepare), validating before
deploy (use azure-validate), Azure Functions specifically (use azure-functions).
INVOKES: azure-azd MCP (up, deploy, provision), azure-deploy MCP (plan_get).
FOR SINGLE OPERATIONS: Use azure-azd MCP directly for single azd commands.
---
High score achieved with:
**WORKFLOW SKILL**)INVOKES: lists MCP tools usedFOR SINGLE OPERATIONS: guides when to bypass skillBefore (empty):
const shouldTriggerPrompts = [];
const shouldNotTriggerPrompts = [];
After:
const shouldTriggerPrompts = [
'Extract text from this PDF',
'Rotate this PDF 90 degrees',
'Merge these PDF files together',
'Split this PDF into pages',
'Convert PDF to text',
];
const shouldNotTriggerPrompts = [
'Create a new PDF document',
'Extract images from this PDF',
'OCR this scanned document',
'What is the weather today?',
'Help me with AWS S3',
];
Ensure shouldTriggerPrompts match "USE FOR:" phrases and shouldNotTriggerPrompts match "DO NOT USE FOR:" scenarios.
Common causes: description > 1024 chars, anti-triggers not using "DO NOT USE FOR:" format, or conflicting triggers with other skills.
git reset --soft HEAD~1 # Undo last commit
SKILL.md for instruction changesreferences/*.md for documentation changesnpm run tokens -- checkreferences/scoring.mdreferences/examples.mdreferences/test-templates/{framework}.mdSensei supports Waza-style trigger accuracy testing. See the Waza test template.
Open an issue with skill name, starting state, and git log --oneline -10.
Sensei - "The path to compliance begins with a single trigger." 🥋
TypeScript
74.0%
Python
17.2%
JavaScript
5.7%
Shell
3.0%