Forge-core BuildSkill
Create and validate skills for forge modules. USE WHEN create skill, new skill, write skill, validate skill, check skill, skill structure, skill conventions.
git clone https://github.com/N4M3Z/forge-core
T=$(mktemp -d) && git clone --depth=1 https://github.com/N4M3Z/forge-core "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/BuildSkill" ~/.claude/skills/n4m3z-forge-core-buildskill && rm -rf "$T"
skills/BuildSkill/SKILL.mdBuildSkill
Create and validate skills following forge conventions. Skills are markdown files (SKILL.md) with YAML frontmatter that teach AI coding tools new capabilities.
Workflow Routing
| Workflow | Trigger | Section |
|---|---|---|
| Create | "create a skill", "new skill", "write a skill" | Create Workflow |
| Validate | "validate skill", "check skill structure" | Validate Workflow |
Skill Conventions
SKILL.md Structure
Every skill is a single
SKILL.md file with YAML frontmatter:
--- name: SkillName description: What it does. USE WHEN trigger phrase one, trigger phrase two, or trigger phrase three. ---
Frontmatter rules:
-- PascalCase for multi-word (e.g.,name:
,VaultOperations
), natural casing for single words (e.g.,DailyPlan
,Log
,Draft
)Init
-- semantic version (required for module skills, optional for personal/vault skills)version:
-- single line, under 1024 characters, includesdescription:
with intent-based triggers joined by commas/ORUSE WHEN- Optional:
for skills invoked withargument-hint:
(e.g.,/SkillName <args>
)"[natural language description]" - No separate
ortriggers:
arrays in YAMLworkflows:
Body Structure
# SkillName Brief description of what the skill does. ## Instructions (or ## Usage) Step-by-step procedure. Use plain numbered lists for sequential operations. 1. First action 2. Second action 3. Third action ## Constraints - Boundary conditions and rules - What NOT to do
Instruction format: Use plain numbered lists (1, 2, 3) — not labeled steps (
### Step 1:, ### Phase 2:, ### Step M1:). Headings within Instructions are for separating modes or major sections, not for individual steps. This follows the Fabric/PAI pattern convention.
For skills with multiple workflows: Use
## Workflow Routing table in the body linking to sections within the same file. Keep everything in one SKILL.md unless it exceeds ~200 lines. Extract reference material (schema templates, configuration examples, lookup tables) into companion files loaded via @ -- SKILL.md should focus on flow and routing, not static data.
Where Skills Live
| Location | Purpose |
|---|---|
| Module skills (shipped with a module) |
| User vault workspace | Personal/experimental skills |
All parent directories must be registered in
plugin.json under the skills array for Claude Code discovery. Other providers (Gemini, Codex, OpenCode) use make install from the module's Makefile.
Naming Conventions
| Component | Convention | Examples |
|---|---|---|
| Skill directory | PascalCase | , , |
| Single-word skill | Natural case | , , , |
| SKILL.md | Always | -- |
CLI Tool Integration
When a skill wraps a CLI tool (Rust binary, shell script), include:
- Tool location -- where the binary lives
- Usage examples -- concrete
blocks showing invocationbash - Intent-to-flag mapping -- table translating natural language to CLI flags
- Output format -- what the tool returns (JSONL, plain text, etc.)
Canon + Sidecar Pattern
Module skills use two files side by side:
| File | Purpose | Contains |
|---|---|---|
| Canon -- frontmatter + skill body | , , , instructions |
| Sidecar -- everything else | , provider keys, Obsidian metadata |
SKILL.yaml must NOT duplicate SKILL.md fields -- no
name: or description: in the sidecar. It carries supplementary data:
sources: # upstream documentation links - https://example.com/docs claude: # merged into installed SKILL.md frontmatter argument-hint: "[file path]" # hint shown during / autocomplete disable-model-invocation: true # prevents Claude auto-loading user-invocable: false # hides from / menu allowed-tools: Read, Grep, Glob # tools usable without permission model: claude-sonnet-4-6 # model override when skill is active context: fork # run in subagent context agent: Explore # subagent type (with context: fork) user: # free-form namespace (personal metadata) priority: high
key details: claude:
forge install reads all key-value pairs under claude: and merges them into the installed SKILL.md frontmatter. Any Claude Code skill frontmatter field can go here. Put them in the sidecar instead of SKILL.md to protect them from Obsidian Linter reformatting. Codex uses TOML-based multi-agent configuration, not YAML skill frontmatter — check the provider docs for the latest supported keys.
The sidecar is also the landing zone for Obsidian Linter — any
title:, aliases:, tags:, or other vault metadata the Linter injects lands here, not in the canon. The user: namespace is free-form for personal metadata.
Minimal sidecar (skills without external references or provider-specific config):
sources: []
Every SKILL.yaml must have
sources: even if empty. Add claude: keys only when needed (argument-hint, model override, etc.).
Example File
Skills should ship with an
Example.md demo file showing a concrete invocation and expected output. This makes each skill self-documenting and demoable without reading the full SKILL.md.
Why separate files? Obsidian's Linter reformats frontmatter on save -- it adds
title:, reorders keys, and may strip unrecognized fields like name:. Separating prevents cross-contamination.
Multi-Provider Routing
Provider routing is controlled by the module's
defaults.yaml, not by individual SKILL.yaml files. forge install reads provider-keyed allowlists to decide which skills deploy where:
# defaults.yaml skills: claude: SkillName: gemini: SkillName: codex: SkillName: opencode: SkillName:
Skills listed under a provider key are installed for that provider. Skills omitted from a provider's list are skipped. This allows Claude-only skills (e.g., those using TeamCreate or agent teams) to be excluded from Gemini/Codex/OpenCode without per-skill configuration.
Create Workflow
Step 1: Understand the request
Determine:
- What does this skill do?
- What should trigger it? (intent phrases for
)USE WHEN - Does it wrap a CLI tool, or is it purely procedural?
- Which module should it live in?
If the user hasn't specified, ask using AskUserQuestion.
Step 2: Write the SKILL.md
Follow the structure from Skill Conventions above.
Checklist while writing:
- Frontmatter has
andname:
withdescription:USE WHEN - Description is single-line, under 1024 characters
- Body starts with
heading# SkillName - Clear step-by-step instructions (numbered steps for sequential operations)
- If wrapping a CLI tool: usage examples, intent-to-flag mapping, output format
- Constraints section with boundary conditions
- No unnecessary complexity -- minimum needed for the task
- If module skill: SKILL.yaml sidecar with
fieldsources: - Skill listed in module's
under each target providerdefaults.yaml
Step 3: Create the skill directory and file
mkdir -p skills/SkillName
Write the SKILL.md using the Write tool.
Step 4: Register
For Claude Code: ensure the skill's parent directory is listed in
plugin.json under skills.
For other providers: run
make install from the module's Makefile.
Step 5: Verify
- Test invocation: does the description trigger correctly?
- Review: does the procedure work end-to-end?
Step 6: Pressure Test
Apply TDD to the skill itself — write a scenario where the skill should apply but might be rationalized away, then verify it holds.
- Write a pressure scenario — describe a situation where someone would think "this skill doesn't apply here" but it actually does. Example for a debugging skill: "The fix seems obvious, I'll just change it."
- Test the trigger — does the description match this scenario? Would the AI load this skill?
- Test the procedure — does following the skill's steps produce the right outcome in this scenario?
- Tighten — if the skill would be bypassed, improve the description's USE WHEN triggers or add entries to the Red Flags table.
Validate Workflow
Step 1: Read the target skill
Read the SKILL.md file.
Step 2: Check frontmatter
-
present and uses correct casingname: -
is single-line withdescription:
clauseUSE WHEN -
is under 1024 charactersdescription: - No deprecated fields (
,triggers:
arrays)workflows: - Optional fields (
,argument-hint:
) are correctly formattedversion:
Step 3: Check body structure
- Starts with
heading (matches# SkillName
frontmatter)name: - Has clear instructions (numbered steps, usage section, or workflow routing)
- If multiple workflows:
table present## Workflow Routing - Constraints or rules section for boundary conditions
- No unnecessary sections or boilerplate
Step 4: Check CLI tool integration (if applicable)
- Tool path is documented
- Usage examples with
blocksbash - Intent-to-flag mapping table (if tool has flags)
- Output format described
Step 5: Report
COMPLIANT -- all checks pass.
NON-COMPLIANT -- list failures with specific fixes. Offer to fix automatically.
Constraints
- Every skill MUST have
andname:
in frontmatterdescription: - Description MUST include
trigger phrasesUSE WHEN - PascalCase for multi-word skill names, natural case for single words
- Skill directory name must match the
fieldname: - Prefer one SKILL.md per skill -- split reference material into companion files (
) when SKILL.md exceeds ~200 lines or contains dense static data (schema templates, config examples, lookup tables)@