/frontmatter-guard
Validate and auto-repair YAML frontmatter on brain pages. Catches malformed pages before they enter the brain (missing closing ---, nested quotes, slug mismatches, null bytes, empty frontmatter, YAML parse failures), explains files sync holds instead of importing, and drives the
Claude Code
$ npx -y skills add garrytan/gbrain --skill frontmatter-guard --agent claude-code
Codex
$ npx skills add garrytan/gbrain --skill frontmatter-guard -a codex -y
Cursor
$ npx skills add garrytan/gbrain --skill frontmatter-guard -a cursor -y
Gemini CLI
$ npx skills add garrytan/gbrain --skill frontmatter-guard -a gemini-cli -y
GitHub Copilot
$ npx skills add garrytan/gbrain --skill frontmatter-guard -a github-copilot -y
OpenCode
$ npx skills add garrytan/gbrain --skill frontmatter-guard -a opencode -y
Windsurf
$ npx skills add garrytan/gbrain --skill frontmatter-guard -a windsurf -y
SKILL.md
frontmatter-guard.SKILL.mdname: frontmatter-guard
version: 1.1.0
description: |
Validate and auto-repair YAML frontmatter on brain pages. Catches malformed
pages before they enter the brain (missing closing ---, nested quotes, slug
mismatches, null bytes, empty frontmatter, YAML parse failures), explains
files sync holds instead of importing, and drives the previewed
`gbrain repair frontmatter` fix. Wraps the `gbrain frontmatter` CLI for
agent-driven workflows.
triggers:
- "validate frontmatter"
- "check frontmatter"
- "fix frontmatter"
- "frontmatter audit"
- "brain lint"
- "held files"
- "sync held a file"
tools:
- exec
mutating: true
Frontmatter Guard Skill
> **Convention:** see `skills/conventions/quality.md` for citation rules; this skill is structural validation, not citation auditing.
Contract
This skill guarantees:
- Every brain page is scanned against the eight canonical frontmatter validation classes
- Mechanical errors (nested quotes, missing closing `---`, null bytes, slug mismatch) are auto-repairable on demand with `.bak` backups
- Validation logic is shared with `gbrain doctor`'s `frontmatter_integrity` subcheck — single source of truth
- Reports per source (gbrain is multi-source since v0.18.0); never silently audits the wrong root
- Files sync holds are explained from their hold record (code, reason, key, line, fix) and fixed only through a previewed, hash-bound repair the user approved
Why This Exists
Brain pages pile up over months. Agents write them with malformed frontmatter:
- Missing closing `---` (entity detector bugs)
- Unstructured YAML in meeting pages (ingestion bugs)
- Slug mismatches (path renames not propagated)
- Null bytes (binary corruption from copy-paste accidents)
- Nested double quotes in titles (`title: "Alice "Ace" Example"`)
Without a guard, these accumulate silently until `gbrain sync` chokes or search returns garbage. The guard makes the failure visible at audit time and trivially fixable.
Write brain files safely (do this first)
- Write pages through `put_page` / `capture` (MCP or `gbrain put`). gbrain serializes frontmatter itself, so the file on disk is always valid YAML.
- A script or agent that writes Markdown files directly must build frontmatter with a YAML serializer (`yaml.dump`, js-yaml `dump`), never by string interpolation. `title: ${title}` breaks as soon as a title contains `: `, `#`, quotes or a newline.
- Check generated content before writing it, without touching disk:
printf '%s' "$content" | gbrain frontmatter validate --stdin --path notes/2026-10-04-digest.md
Exit 1 means fix it first. The default is the strict producer rule: YAML gbrain could still import by quoting a value fails too, because other tools reject it. `--importable` answers the narrower question "would sync hold it?".
- Never write a key gbrain reads for access or identity (`visibility`, `derived_from`, `slug`, `type`, `id`, `source_id`) from untrusted text.
- Write no `visibility`, `access`, `confidentiality` or `readable_by` unless the page needs it ([page privacy](../conventions/page-privacy.md)).
Held files: read them, then fix them
A file sync cannot import without guessing is **held**: the rest of the source still syncs, a new file has no page yet, and an existing page keeps its last good revision and refuses `put_page` until the file is repaired (do not retry the write). Where holds show up: sync output (`Held <path>: <code> … Next: <command>`), `gbrain sources status <id>` (`--json`: `git_holds.items[]`), doctor `git_held_files`, `get_page` `file_held`, and search hits marked `stale`.
Each hold record carries `code`, `reason`, `key`, `line`, `message` (location only, never the value), `fix` (exact argv) and `docs`. Act on `reason`:
| Hold | What to do | |------|-----------| | `invalid_frontmatter` / `yaml_parse` | Preview `gbrain repair frontmatter --source <id>`; usually `needs_review` with the exact line to fix by hand. | | `invalid_frontmatter` / `needs_interpretation` | Preview with `--include-ambiguous`, show the user each per-file diff, apply only what they approve. | | `invalid_frontmatter` / `ambiguous_identity_key` or `ambiguous_protected_key`; `visibility_noncanonical` | Never guess. Show the user the line; they decide the one value (`visibility` decides who can read the page; page privacy reads only `visibility: private`, lowercase on its own line). | | `frontmatter_slug_conflict` | Remove the `slug:` line or move the file; the repair proposes removing it under `--include-ambiguous`. | | `file_too_large` | The file is over the fixed page limit (24 MiB for Markdown, 5 MB for code); every page under it is searchable, so never split one that fits. Ask the user to add it to `sync.exclude`, or to split it into files under the limit. A smaller page an MCP transport refused goes by file instead (`docs/guides/memory-boundaries.md#large-page-limits`). | | `content_rejected` | The user chose `content_sanity.junk_disposition=reject`; ask before changing it. |
The fix flow (walkthrough with real output: `docs/guides/repair.md#held-files`):
gbrain sources status <id> # what is held and why
gbrain repair frontmatter --source <id> # pass 1: safe quoting only; writes nothing
gbrain repair frontmatter --source <id> --include-ambiguous --diff # pass 2: every interpretation
gbrain repair frontmatter --source <id> --include-ambiguous --only <path> --apply --expect <hash> --yes
**Ask the user before** every `--apply` (it rewrites their files) and before any `--include-ambiguous` apply: each interpretation (folding lines into a title, keeping the later duplicate) is a guess only the user can confirm. Show the diff, then apply exactly the previewed hash. Safe-class changes only quote a value exactly as gbrain already reads it, but they still rewrite files, so they need the same agreement.
A source that a broken file blocked before the up
Read more
name: frontmatter-guard version: 1.1.0 description: | Validate and auto-repair YAML frontmatter on brain pages. Catches malformed pages before they enter the brain (missing closing ---, nested quotes, slug mismatches, null bytes, empty frontmatter, YAML parse failures), explains files sync holds instead of importing, and drives the previewed `gbrain repair frontmatter` fix. Wraps the `gbrain frontmatter` CLI for agent-driven workflows. triggers: - "validate frontmatter" - "check frontmatter" - "fix frontmatter" - "frontmatter audit" - "brain lint" - "held files" - "sync held a file" tools: - exec mutating: true
Frontmatter Guard Skill
> **Convention:** see `skills/conventions/quality.md` for citation rules; this skill is structural validation, not citation auditing.
Contract
This skill guarantees:
- Every brain page is scanned against the eight canonical frontmatter validation classes
- Mechanical errors (nested quotes, missing closing `---`, null bytes, slug mismatch) are auto-repairable on demand with `.bak` backups
- Validation logic is shared with `gbrain doctor`'s `frontmatter_integrity` subcheck — single source of truth
- Reports per source (gbrain is multi-source since v0.18.0); never silently audits the wrong root
- Files sync holds are explained from their hold record (code, reason, key, line, fix) and fixed only through a previewed, hash-bound repair the user approved
Why This Exists
Brain pages pile up over months. Agents write them with malformed frontmatter:
- Missing closing `---` (entity detector bugs)
- Unstructured YAML in meeting pages (ingestion bugs)
- Slug mismatches (path renames not propagated)
- Null bytes (binary corruption from copy-paste accidents)
- Nested double quotes in titles (`title: "Alice "Ace" Example"`)
Without a guard, these accumulate silently until `gbrain sync` chokes or search returns garbage. The guard makes the failure visible at audit time and trivially fixable.
Write brain files safely (do this first)
- Write pages through `put_page` / `capture` (MCP or `gbrain put`). gbrain serializes frontmatter itself, so the file on disk is always valid YAML.
- A script or agent that writes Markdown files directly must build frontmatter with a YAML serializer (`yaml.dump`, js-yaml `dump`), never by string interpolation. `title: ${title}` breaks as soon as a title contains `: `, `#`, quotes or a newline.
- Check generated content before writing it, without touching disk:
printf '%s' "$content" | gbrain frontmatter validate --stdin --path notes/2026-10-04-digest.md
Exit 1 means fix it first. The default is the strict producer rule: YAML gbrain could still import by quoting a value fails too, because other tools reject it. `--importable` answers the narrower question "would sync hold it?".
- Never write a key gbrain reads for access or identity (`visibility`, `derived_from`, `slug`, `type`, `id`, `source_id`) from untrusted text.
- Write no `visibility`, `access`, `confidentiality` or `readable_by` unless the page needs it ([page privacy](../conventions/page-privacy.md)).
Held files: read them, then fix them
A file sync cannot import without guessing is **held**: the rest of the source still syncs, a new file has no page yet, and an existing page keeps its last good revision and refuses `put_page` until the file is repaired (do not retry the write). Where holds show up: sync output (`Held <path>: <code> … Next: <command>`), `gbrain sources status <id>` (`--json`: `git_holds.items[]`), doctor `git_held_files`, `get_page` `file_held`, and search hits marked `stale`.
Each hold record carries `code`, `reason`, `key`, `line`, `message` (location only, never the value), `fix` (exact argv) and `docs`. Act on `reason`:
| Hold | What to do | |------|-----------| | `invalid_frontmatter` / `yaml_parse` | Preview `gbrain repair frontmatter --source <id>`; usually `needs_review` with the exact line to fix by hand. | | `invalid_frontmatter` / `needs_interpretation` | Preview with `--include-ambiguous`, show the user each per-file diff, apply only what they approve. | | `invalid_frontmatter` / `ambiguous_identity_key` or `ambiguous_protected_key`; `visibility_noncanonical` | Never guess. Show the user the line; they decide the one value (`visibility` decides who can read the page; page privacy reads only `visibility: private`, lowercase on its own line). | | `frontmatter_slug_conflict` | Remove the `slug:` line or move the file; the repair proposes removing it under `--include-ambiguous`. | | `file_too_large` | The file is over the fixed page limit (24 MiB for Markdown, 5 MB for code); every page under it is searchable, so never split one that fits. Ask the user to add it to `sync.exclude`, or to split it into files under the limit. A smaller page an MCP transport refused goes by file instead (`docs/guides/memory-boundaries.md#large-page-limits`). | | `content_rejected` | The user chose `content_sanity.junk_disposition=reject`; ask before changing it. |
The fix flow (walkthrough with real output: `docs/guides/repair.md#held-files`):
gbrain sources status <id> # what is held and why gbrain repair frontmatter --source <id> # pass 1: safe quoting only; writes nothing gbrain repair frontmatter --source <id> --include-ambiguous --diff # pass 2: every interpretation gbrain repair frontmatter --source <id> --include-ambiguous --only <path> --apply --expect <hash> --yes
**Ask the user before** every `--apply` (it rewrites their files) and before any `--include-ambiguous` apply: each interpretation (folding lines into a title, keeping the later duplicate) is a guess only the user can confirm. Show the diff, then apply exactly the previewed hash. Safe-class changes only quote a value exactly as gbrain already reads it, but they still rewrite files, so they need the same agreement.
A source that a broken file blocked before the up
Other skills on gbrain.
More skills from other plugins.
agent-cost-report
Believable agent cost report for any period, default the last 7 full days PT, not counting today. Measured tokens from Claude…
bot-handoff
Keep a durable record of work passed between Bots in the shared Hindsight memory bank. Use when handing work to another Bot, when…
mempalace
Install, configure, and operate MemPalace, including a private local palace, a shared-brain hub, or a client joining an existing…
mempalace
Install, configure, and operate MemPalace, including a private local palace, a shared-brain hub, or a client joining an existing…
Questions about frontmatter-guard.
- Which coding agents can use frontmatter-guard?
- frontmatter-guard installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.

