RFC-0008: Skill Authoring Standard
Version: 0.2.1 | Status: normative | Phase: test
1. Summary
[RFC-0008:C-OVERVIEW] Overview (Informative)
This RFC defines the skill authoring standard as a set of configurable lint rules that skc lint applies to skill directories.
Design:
- Each rule has a unique identifier (SKLxxx)
- Rules are grouped by category (frontmatter, structure, links, files)
- Rules produce diagnostic output per RFC-0005
- Rules will be configurable in a future version (see RFC-0008:C-EXTENSIONS)
Rule categories:
- SKL1xx: Frontmatter validation rules
- SKL2xx: Structure and content rules
- SKL3xx: Link validation rules
- SKL4xx: File organization rules
Relationship to other RFCs:
- RFC-0001 defines compilation requirements; this RFC extends with quality validation
- RFC-0005 defines diagnostic output format; rules map to diagnostic codes
Since: v0.1.0
2. Specification
[RFC-0008:C-REGISTRY] Rule Registry (Normative)
This clause defines all lint rules. Each rule has an ID, name, default severity, and description.
Frontmatter Definition
SKILL.md frontmatter is a YAML block delimited by --- lines:
- The file MUST begin with a line containing exactly
--- - The frontmatter ends at the next line containing exactly
--- - Content between the delimiters is parsed as YAML
Frontmatter validation is handled by rule SKL100.
Rule Summary
| Rule ID | Name | Default | Category |
|---|---|---|---|
| SKL001 | skip-compiled | n/a | Meta |
| SKL100 | frontmatter-valid | error | Frontmatter |
| SKL101 | name-required | error | Frontmatter |
| SKL102 | name-format | error | Frontmatter |
| SKL103 | name-length | error | Frontmatter |
| SKL104 | name-match-dir | warning | Frontmatter |
| SKL105 | description-required | error | Frontmatter |
| SKL106 | description-nonempty | error | Frontmatter |
| SKL107 | description-length | warning | Frontmatter |
| SKL108 | description-triggers | warning | Frontmatter |
| SKL109 | frontmatter-known | warning | Frontmatter |
| SKL201 | skill-size | warning | Structure |
| SKL202 | heading-h1 | warning | Structure |
| SKL203 | heading-match-name | warning | Structure |
| SKL204 | heading-first-h1 | warning | Structure |
| SKL205 | heading-hierarchy | warning | Structure |
| SKL301 | link-file-exists | error | Links |
| SKL302 | link-anchor-exists | warning | Links |
| SKL303 | link-no-escape | error | Links |
| SKL401 | no-orphans | warning | Files |
Meta Rules (SKL0xx)
SKL001: skip-compiled
Skip linting for compiled skills (detected by .skillc-meta/manifest.json).
Default behavior: enabled (compiled skills are skipped)
When a compiled skill is detected and this rule is enabled:
- The linter prints:
info: skipping compiled skill '<name>' - Exits with code 0 (success)
When --force is used, this rule is disabled and:
- The linter emits:
warning[W300]: SKL001 skip-compiled: linting compiled skill; results may not be meaningful - Applies all other rules normally
Configurability: Unlike other rules, SKL001 is controlled by --force, not by rule configuration. Future versions MAY allow disabling it via config.
Rationale: Compiled skills are derived artifacts. Their generated stub differs from source content.
Frontmatter Rules (SKL1xx)
SKL100: frontmatter-valid
SKILL.md MUST have valid frontmatter delimiters and parseable YAML.
Default severity: error
Requirements:
- File MUST begin with a line containing exactly
--- - A second
---line MUST appear to close the frontmatter - Content between delimiters MUST be valid YAML
Error messages:
- Missing opening delimiter:
missing frontmatter: file does not start with --- - Missing closing delimiter:
missing frontmatter: no closing --- found - YAML parse error:
invalid frontmatter YAML: <parse-error>
SKL101: name-required
The name field MUST be present in SKILL.md frontmatter.
Default severity: error
SKL102: name-format
The name field MUST contain only lowercase ASCII letters (a-z), digits (0-9), and hyphens (-). It MUST NOT start or end with a hyphen.
Default severity: error
Valid: my-skill, skill123, a
Invalid: My-Skill (uppercase), -skill (leading hyphen), skill_name (underscore)
SKL103: name-length
The name field MUST be 1-64 characters in length.
Default severity: error
SKL104: name-match-dir
The name field SHOULD match the skill directory name.
Default severity: warning
SKL105: description-required
The description field MUST be present in SKILL.md frontmatter.
Default severity: error
SKL106: description-nonempty
The description field MUST NOT be empty or whitespace-only.
Default severity: error
SKL107: description-length
The description field SHOULD be at most 1024 characters.
Default severity: warning
SKL108: description-triggers
The description field SHOULD include activation triggers.
Default severity: warning
Detection: The rule checks for presence of any of these English patterns (case-insensitive):
use whenwhen to useuse fortriggers ontriggers:activate when
Note: This rule is designed for English-language skills. Non-English skills may disable this rule via configuration (future).
SKL109: frontmatter-known
Frontmatter fields SHOULD be from the known set.
Default severity: warning
Known fields:
name(required)description(required)allowed-tools(optional, implementation-defined behavior)
Unknown fields trigger a warning. This helps catch typos and misunderstandings of the schema.
Note on allowed-tools: This field is recognized by some agent implementations to restrict available tools. Its format and semantics are implementation-defined. Future versions MAY add validation rules for this field.
Structure Rules (SKL2xx)
SKL201: skill-size
SKILL.md SHOULD be at most 500 lines.
Default severity: warning
SKL202: heading-h1
SKILL.md SHOULD contain at least one H1 (#) heading.
Default severity: warning
SKL203: heading-match-name
The first H1 heading in SKILL.md SHOULD match or contain the skill name.
Default severity: warning
Matching: Case-insensitive comparison. The heading may contain additional text (e.g., heading “My Skill Guide” matches name “my-skill” if “my-skill” appears as a substring after normalizing hyphens to spaces).
SKL204: heading-first-h1
The first heading in each markdown file SHOULD be an H1 (#).
Default severity: warning
Scope: Applies to all .md files in the skill directory.
Rationale: The first heading establishes the document title. Starting with H2 or lower suggests missing context.
Since: v0.2.0
SKL205: heading-hierarchy
Headings SHOULD NOT skip levels when going deeper.
Default severity: warning
Scope: Applies to all .md files in the skill directory.
Requirements:
- When increasing heading depth, levels MUST NOT be skipped (H2→H4 is invalid; H2→H3 is valid)
- Decreasing depth is always allowed (H3→H2, H4→H1 are valid)
Examples:
- Valid:
# Title→## Section→### Subsection→## Another Section - Invalid:
# Title→### Subsection(skipped H2) - Invalid:
## Section→#### Deep(skipped H3)
Rationale: Skipped heading levels break document outline semantics and can cause accessibility issues.
Since: v0.2.0
Link Rules (SKL3xx)
SKL301: link-file-exists
Internal markdown file links MUST resolve to existing files within the skill directory.
Default severity: error
Scope: Relative links like [text](path/to/file.md). Absolute paths and external URLs are not checked.
SKL302: link-anchor-exists
Internal markdown anchor links SHOULD resolve to existing headings.
Default severity: warning
Anchor normalization: GitHub-style slugging for ASCII:
- Convert to lowercase
- Remove characters except
a-z,0-9, spaces, hyphens - Replace spaces with hyphens
- Collapse consecutive hyphens
Non-ASCII characters are removed. For duplicate headings, anchors are suffixed: #heading, #heading-1.
SKL303: link-no-escape
Links MUST NOT escape the skill root directory via .. traversal.
Default severity: error
File Rules (SKL4xx)
SKL401: no-orphans
Markdown files in the skill directory SHOULD be reachable from SKILL.md via link traversal.
Default severity: warning
Definition: A file is orphaned if it is not SKILL.md and is not reachable via links starting from SKILL.md (transitive closure).
Exceptions: Not considered orphaned:
- Files in hidden directories (starting with
.) - Common non-content files:
LICENSE.md,CHANGELOG.md,CONTRIBUTING.md,README.md
Since: v0.1.0
[RFC-0008:C-SCOPE] Lint Scope (Normative)
This clause defines what files the linter scans.
File Scanning
The linter scans all .md files in the skill directory, excluding:
- Files in directories starting with
.(e.g.,.git/,.skillc-meta/,.github/) - Files whose names start with
.
This is consistent with RFC-0001 compilation behavior.
Compiled Skill Detection
Compiled skill handling is defined by rule SKL001 in RFC-0008:C-REGISTRY.
Detection: A skill is compiled if .skillc-meta/manifest.json exists.
SKILL.md Requirement
The linter requires SKILL.md to exist. If missing, the linter exits with E010 per RFC-0005:C-CODES.
Frontmatter Requirement
Frontmatter validation is handled by rule SKL100 in RFC-0008:C-REGISTRY. Invalid frontmatter produces E300 (lint error), not E010.
Since: v0.1.0
[RFC-0008:C-DIAGNOSTICS] Diagnostic Output (Normative)
This clause defines how lint rules produce diagnostic output.
Output Format
All lint diagnostics use the format defined in RFC-0005:C-CODES:
<severity>[<code>]: <rule-id> <rule-name>: <message>
Components:
<severity>:errororwarning<code>:E300for errors,W300for warnings<rule-id>: The rule identifier (e.g.,SKL102)<rule-name>: The rule name (e.g.,name-format)<message>: Human-readable description of the violation
Examples:
error[E300]: SKL102 name-format: name 'My-Skill' contains uppercase characters
error[E300]: SKL301 link-file-exists: link target not found: 'references/missing.md'
warning[W300]: SKL104 name-match-dir: name 'foo' does not match directory 'bar'
warning[W300]: SKL401 no-orphans: orphaned file: 'old-notes.md'
Rule Severity Mapping
Each rule has a default severity (error or warning) defined in RFC-0008:C-REGISTRY.
| Default Severity | Diagnostic Code |
|---|---|
| error | E300 |
| warning | W300 |
Exit Behavior
- If any rule with error severity is violated: exit with status 1
- If only warning-severity rules are violated: exit with status 0
- If no violations: exit with status 0
Machine-Readable Output
Future versions MAY support structured output formats (JSON, SARIF) for tooling integration. See RFC-0008:C-EXTENSIONS.
Since: v0.1.0
[RFC-0008:C-REFERENCE-FRONTMATTER] Reference File Frontmatter (Informative)
Non-SKILL.md markdown files (reference documents) MAY contain optional YAML frontmatter.
Frontmatter Format
Reference files MAY begin with a YAML frontmatter block:
---
description: "Brief description of this reference document"
---
# Reference Title
Content here...
Supported Fields
| Field | Required | Description |
|---|---|---|
description | No | Brief description displayed in compiled stub |
Field Constraints
description:
- Optional (no lint warning if absent)
- Should be ≤120 characters for optimal display
- Longer descriptions are truncated with
…in the stub - Used by the compiler per RFC-0001:C-SECTIONS
Differences from SKILL.md Frontmatter
Reference file frontmatter differs from SKILL.md frontmatter:
| Aspect | SKILL.md | Reference files |
|---|---|---|
| Required | Yes | No |
name field | Required | Not used |
description field | Required | Optional |
| Linting | Full validation | No validation |
Example
A reference file references/clap-patterns.md:
---
description: "Advanced clap argument parsing patterns"
---
# Clap Patterns
## Value Enums
...
This description appears in the compiled stub:
- References
- Clap Patterns — Advanced clap argument parsing patterns
Since: v0.2.0
3. Extensions
[RFC-0008:C-EXTENSIONS] Future Extensions (Informative)
This clause describes planned future extensions. These are NOT part of v0.2.0.
Configurable Rules (Future)
A future version MAY support rule configuration via .skilllint.toml:
# Example future configuration (not implemented)
[rules]
SKL107 = "off" # Disable description length check
SKL201 = { max-lines = 300 } # Custom threshold
SKL108 = "error" # Upgrade warning to error
Design considerations:
- Configuration file location: skill root or global
~/.config/skillc/ - Per-rule enable/disable
- Severity override (error ↔ warning ↔ off)
- Rule-specific parameters (thresholds, patterns)
Inline Directives (Future)
A future version MAY support inline directives to suppress warnings:
<!-- skilllint-disable SKL201 -->
[large content here]
<!-- skilllint-enable SKL201 -->
Or single-line suppression:
[very long line] <!-- skilllint-disable-line SKL... -->
Structured Output (Future)
A future version MAY support machine-readable output:
--format=json— JSON array of violations--format=sarif— SARIF format for IDE integration
Additional Rules (Future)
Potential future rules:
- SKL110:
allowed-tools-known— warn on unrecognized tool names - SKL206:
code-block-language— code blocks should have language tags - SKL207:
line-length— lines should not exceed threshold
Note: These extensions are documented for planning. They are out of scope for v0.2.0.
Since: v0.1.0
Changelog
v0.2.1 (2026-01-31)
Add C-REFERENCE-FRONTMATTER for optional description in reference files
v0.2.0 (2026-01-31)
Normalize SKL204, SKL205
v0.1.0 (2026-01-30)
Initial release