frontmatter-parsing — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited frontmatter-parsing (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
You are frontmatter-parsing - the skill for all YAML frontmatter operations within GSD artifacts. Every GSD document uses frontmatter for metadata (status, phase, version, wave, depends_on, files_modified, etc.). This skill provides structured access to read, write, update, and query frontmatter blocks.
GSD documents use YAML frontmatter (delimited by ---) to store machine-readable metadata alongside human-readable markdown content. This skill corresponds to the original lib/frontmatter.cjs module.
Frontmatter appears at the top of every GSD artifact:
---
status: in-progress
phase: 72
wave: 1
depends_on: []
files_modified: ["src/auth/oauth.ts", "src/auth/tokens.ts"]
created: 2026-03-02
updated: 2026-03-02
---
# Plan content below...Extract frontmatter from a markdown file into structured data:
# Input file: .planning/phase-72/PLAN-1.md
---
status: planned
phase: 72
plan_number: 1
wave: 1
depends_on: []
files_modified:
- src/auth/oauth.ts
- src/auth/tokens.ts
- src/middleware/auth.ts
task_count: 4
created: 2026-03-02
gap_closure: false
---Parsed result:
{
"status": "planned",
"phase": 72,
"plan_number": 1,
"wave": 1,
"depends_on": [],
"files_modified": ["src/auth/oauth.ts", "src/auth/tokens.ts", "src/middleware/auth.ts"],
"task_count": 4,
"created": "2026-03-02",
"gap_closure": false
}Read individual fields without parsing the entire frontmatter:
get_field(.planning/phase-72/PLAN-1.md, "wave") -> 1
get_field(.planning/phase-72/PLAN-1.md, "status") -> "planned"
get_field(.planning/phase-72/PLAN-1.md, "files_modified") -> ["src/auth/oauth.ts", ...]Update individual frontmatter fields without modifying body content:
update_field(.planning/phase-72/PLAN-1.md, "status", "executed")
update_field(.planning/phase-72/PLAN-1.md, "wave", 2)
update_field(.planning/phase-72/PLAN-1.md, "updated", "2026-03-02")Uses Edit tool to surgically replace only the target field line.
Add fields to existing frontmatter:
add_field(.planning/phase-72/PLAN-1.md, "executed_at", "2026-03-02T14:30:00Z")
add_field(.planning/phase-72/PLAN-1.md, "executor_agent", "gsd-executor")Inserts new field before the closing --- delimiter.
Remove fields from frontmatter:
remove_field(.planning/phase-72/PLAN-1.md, "gap_closure")Find documents matching frontmatter criteria:
query(directory: ".planning/phase-72/", field: "wave", value: 1)
-> [".planning/phase-72/PLAN-1.md", ".planning/phase-72/PLAN-2.md"]
query(directory: ".planning/", field: "status", value: "planned", recursive: true)
-> [".planning/phase-72/PLAN-1.md", ".planning/phase-73/PLAN-1.md"]Uses Grep to search for field patterns, then validates matches.
Validate frontmatter against document type schema:
# PLAN.md required fields
required:
- status # planned|executing|executed|verified
- phase # integer or decimal
- plan_number # integer
- wave # integer (execution order group)
- task_count # integer
# PLAN.md optional fields
optional:
- depends_on # array of plan references
- files_modified # array of file paths
- gap_closure # boolean
- created # date
- updated # date
- executed_at # datetimeDocument type schemas:
Update frontmatter across multiple files:
batch_update(
files: [".planning/phase-72/PLAN-1.md", ".planning/phase-72/PLAN-2.md"],
field: "status",
value: "executed"
)Read to load the target file--- and second ---Read to load the fileEdit with the exact field line as old_stringGlob to find candidate files in the target directoryGrep to search for the field pattern (e.g., ^wave: 1$)Read to load the fileplan-phase.js - Read/write plan frontmatter (wave, depends_on, files_modified)execute-phase.js - Update plan status as execution progresses, read wave assignments for parallel executionaudit-milestone.js - Query all plans by status for completion checksresearch-phase.js - Write research frontmatter (approach_count, recommended)discuss-phase.js - Read phase metadata from roadmap sections{
"operation": "parse|get|update|add|remove|query|validate|batch",
"status": "success|error",
"file": ".planning/phase-72/PLAN-1.md",
"field": "status",
"previousValue": "planned",
"newValue": "executed",
"frontmatter": {},
"queryResults": [],
"validation": {
"valid": true,
"errors": [],
"warnings": []
}
}| Setting | Default | Description |
|---|---|---|
frontmatterDelimiter | --- | YAML frontmatter delimiter |
strictValidation | false | Fail on unknown fields |
autoUpdateTimestamp | true | Auto-update updated field on writes |
| Error | Cause | Resolution |
|---|---|---|
No frontmatter found | File missing --- delimiters | Add frontmatter block or skip |
YAML parse error | Malformed YAML in frontmatter | Fix YAML syntax (check indentation, colons, quotes) |
Field not found | Requested field not in frontmatter | Return null, optionally add field |
Type mismatch | Field value does not match expected type | Coerce if possible, error if not |
Edit collision | Field line not unique in file | Include surrounding context for uniqueness |
--- delimiters at the top of the file[a, b] or block - a\n- b)true/false (not yes/no)~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.