mcpField
F
frontmatter-guard

frontmatter-guard

github.com/garrytanドキュメント31.3k235 回インストール今日更新
リポジトリ

frontmatter-guard について

frontmatter-guardは、gbrainの脳ページのメタデータを検証するスキルです。ページを保守するエージェント向けに、監査とバックアップ付き修復を行い、gbrain doctorと検証ロジックを共有します。

主な機能

  1. 018種類のfrontmatter問題を検出
  2. 02ソース別の監査レポート
  3. 03ファイルまたはディレクトリの検証
  4. 04修復をプレビューしてバックアップ
  5. 05コミット前検証フックの導入

活用シーン

  1. 01複数ソースのページ形式を確認
  2. 02CIやコミット前のMarkdown検証
  3. 03同期保留ファイルのfrontmatter修復
  4. 04無効なYAMLの書き込みを予防

MCP 対応

MCP経由でgbrainを使う方法を説明し、監査、検証、ユーザー承認後のファイル修復をエージェントに案内します。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/garrytan/gbrain --skill frontmatter-guard

インストール後、Claude Code で/frontmatter-guardを入力して読み込まれたか確認します。

同梱ファイルrouting-eval.jsonl

詳細

フロントマターガードスキル

規約: 引用ルールについては skills/conventions/quality.md を参照してください。このスキルは構造検証を行うものであり、引用監査は行いません。

契約

このスキルは、次のことを保証します。

  • すべての brain ページが、フロントマターの8つの標準検証クラスに照らしてスキャンされます
  • ネストした引用符、閉じる --- の欠落、ヌルバイト、スラッグの不一致などの機械的なエラーは、要求に応じて .bak バックアップを作成したうえで自動修復できます
  • 検証ロジックは gbrain doctor の frontmatter_integrity サブチェックと共有され、信頼できる情報源が一本化されています
  • ソースごとにレポートされます(gbrain は v0.18.0 以降、複数のソースに対応)。誤ったルートを黙って監査することはありません
  • ファイル同期の保留は、保留レコード(コード、理由、キー、行、修正方法)に基づいて説明され、プレビューを確認したうえでユーザーが承認した、ハッシュに紐づく修復でのみ解消されます

これが必要な理由

brain ページは数か月にわたって蓄積されます。エージェントは、形式が不正なフロントマターを含むページを書き込むことがあります。

  • 閉じる --- の欠落(エンティティ検出器のバグ)
  • 会議ページ内の構造化されていない YAML(取り込み処理のバグ)
  • スラッグの不一致(パス名変更が反映されていない)
  • ヌルバイト(コピー&ペースト時の事故によるバイナリ破損)
  • タイトル内の二重引用符のネスト(title: "Alice "Ace" Example")

ガードがなければ、これらは gbrain sync が失敗したり、検索結果が役に立たなくなったりするまで、気づかれずに蓄積されます。このガードにより、監査時に問題が明らかになり、簡単に修正できます。

brain ファイルを安全に書き込む(最初に実施)

  • put_page / capture(MCP または gbrain put)を通してページを書き込みます。gbrain がフロントマターをシリアライズするため、ディスク上のファイルは常に有効な YAML になります。

  • Markdown ファイルを直接書き込むスクリプトやエージェントは、文字列補間ではなく、YAML シリアライザー(yaml.dump、js-yaml の dump)を使ってフロントマターを作成する必要があります。タイトルに : 、#、引用符、改行が含まれると、title: ${title} は正しく機能しません。

  • ディスクに触れずに、書き込む前に生成した内容を確認します。

    printf '%s' "$content" | gbrain frontmatter validate --stdin --path notes/2026-10-04-digest.md
    

    終了コードが1の場合は、まず修正してください。デフォルトは、厳格な作成ルールです。gbrain が値を引用符で囲めばインポートできる YAML でも、ほかのツールが拒否するため失敗とみなされます。--importable は、より限定的な「同期で保留されるか」という問いに答えます。

  • 信頼できないテキストから、gbrain がアクセスや識別に使うキー(visibility、derived_from、slug、type、id、source_id)を書き込まないでください。

保留されたファイル:読み込んでから修復する

推測なしではインポートできないファイル同期は保留されます。ソースの残りの部分は引き続き同期され、新しいファイルにはまだページが作成されず、既存のページは最後に正常だったリビジョンを保持し、ファイルが修復されるまで put_page を拒否します(書き込みを再試行しないでください)。保留の確認場所:同期の出力(Held <path>: <code> … Next: <command>)、gbrain sources status <id>(--json の場合は git_holds.items[])、doctor の git_held_files、get_page の file_held、および stale とマークされた検索結果。

各保留レコードには、code、reason、key、line、message(場所のみで、値は含まれません)、fix(正確な argv)、docs が含まれます。reason に応じて対処してください。

保留対処方法
invalid_frontmatter / yaml_parsegbrain repair frontmatter --source <id> をプレビューします。通常は needs_review となり、手動で修正する正確な行が示されます。
invalid_frontmatter / needs_interpretation--include-ambiguous を付けてプレビューし、ファイルごとの差分をユーザーに提示して、承認されたものだけを適用します。
invalid_frontmatter / ambiguous_identity_key または ambiguous_protected_key決して推測しないでください。該当行をユーザーに示し、値をユーザーに決めてもらいます(visibility によってページを読める人が決まります)。
frontmatter_slug_conflictslug: 行を削除するか、ファイルを移動します。修復では --include-ambiguous を付けると、該当行の削除が提案されます。
file_too_largeファイルが固定ページ上限(Markdown は 24 MiB、コードは 5 MB)を超えています。その配下のすべてのページが検索可能なので、上限内に収まるファイルを分割しないでください。sync.exclude に追加するか、上限未満のファイルに分割するようユーザーに依頼してください。MCP トランスポートが拒否した小さめのページは、ファイル単位で対処します(docs/guides/memory-boundaries.md#large-page-limits)。
content_rejectedユーザーが content_sanity.junk_disposition=reject を選択しています。変更する前にユーザーに確認してください。

修復の手順(実際の出力を使った手順: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

すべての --apply(ユーザーのファイルを書き換えます)と、--include-ambiguous を付けたすべての適用の前にユーザーに確認してください。行をタイトルにまとめる、後の重複を残すといった各解釈は推測であり、確認できるのはユーザーだけです。差分を見せてから、プレビューされたハッシュと完全に一致する内容を適用してください。安全クラスの変更は、gbrain がすでに読み取っている値をそのまま引用符で囲むだけですが、それでもファイルを書き換えるため、同じ確認が必要です。

アップグレード前にファイルの破損でブロックされていたソースは、次回の同期で復旧します。今すぐ復旧するには、gbrain sync --source <id> --no-pull を実行します。

検証クラス

コード意味自動修復可能か
MISSING_OPENファイルが --- で始まっていないいいえ(人による対応が必要)
MISSING_CLOSE最初の見出しの前に閉じる --- がないはい
YAML_PARSEYAML の解析に失敗した場合による(原因によって異なります)
SLUG_MISMATCHFrontmatter の slug: がパスから導出された slug と異なるはい(フィールドを削除します)
NULL_BYTESバイナリ破損(\x00)はい
NESTED_QUOTEStitle: "outer "inner" outer" の形式はい
NON_STRING_FIELDtitle/type/slug が、引用符で囲まれていない文字列以外のスカラー値(例:title: 123、slug: 2024-06-01)いいえ(値を引用符で囲んでください)
EMPTY_FRONTMATTER開始と終了はあるが、その間に何もないいいえ(人による対応が必要)

フェーズ

フェーズ 1:監査

登録済みのすべてのソース(または --source <id> を指定して1つのソース)を読み取り専用でスキャンします。

gbrain frontmatter audit --json

レポートの内容:

  • エラーコード別に集計したソースごとの件数
  • ソースごとに最大20件の該当ページのサンプル
  • 合計件数
  • スキャンのタイムスタンプ

出力は JSON です。エージェントは errors_by_code と per_source を解析し、次の手順を決定します。

フェーズ 2:1つのパスを検証

単一のファイルまたはディレクトリを検証します(ソースの登録は不要です)。

gbrain frontmatter validate <path> --json

終了コード 0 は問題なし、1 はエラーありです。CI パイプラインや pre-commit フックで使用してください。

Phase 3: 修正

問題が見つかった場合:

gbrain frontmatter validate <path> --fix

--fix は変更するすべてのファイルを変更前に ~/.gbrain/backups/frontmatter/ にバックアップし、gbrain が読み取る YAML に引用符を追加して引用符付きにします(変更されるのは該当行のみ)。その後、再検証を行い、エラーが残っている場合は終了コード 1 で終了します。修正したファイルは git に再ステージしてください(git add)。--include-ambiguous は解釈候補を追加します。まず --dry-run でプレビューしてください。

--dry-run は書き込みを行わずにプレビューします。一括で修正を適用する前に使用してください。

管理対象の brain では、--fix による直接修正は拒否されます。代わりに gbrain repair frontmatter --source <id>(上記)を使用してください。各修正済みファイルは、調整済みのライターを通じて公開されます。

Phase 4: pre-commit フック(任意)

brain リポジトリが git リポジトリでもある場合は、pre-commit フックをインストールし、不正なページがコミットされる前にブロックしてください。

gbrain frontmatter install-hook [--source <id>]

このフックは、ステージされた .md/.mdx ファイルの内容(作業コピーではなく、コミットされる内容)に対して gbrain frontmatter validate --staged を 1 回実行します。git commit --no-verify で回避できます。インストールするとユーザーのリポジトリに書き込むため、事前に確認してください。doctor の frontmatter_hook が古いフックを報告した場合は、gbrain frontmatter install-hook --force で更新してください。

トリガーワード

ユーザーが次のいずれかを言った場合は、ここに誘導します。

  • 「frontmatter を検証」
  • 「frontmatter をチェック」
  • 「frontmatter を修正」
  • 「frontmatter の監査」
  • 「brain の lint」

出力ルール

  • 必ず最初に gbrain frontmatter audit --json を実行してください。brain が問題のない状態だと決めつけてはいけません。
  • 件数はユーザーにわかりやすい言葉で伝えてください。生の JSON をそのまま出力してはいけません。
  • --fix を実行する場合は、実行前に変更されるファイル数を伝え、その後に確認を取ってください。
  • SLUG_MISMATCH の修正では frontmatter の slug: フィールドが削除されます。gbrain はパスから slug を導出します。ユーザーが意図的にタイトルを変更した場合は、その点に触れてください。
  • MISSING_OPEN または EMPTY_FRONTMATTER は、明示的なユーザー入力がない限り自動修正してはいけません。これらは通常、人間の作成者がページの執筆を始めたものの、完了していないことを示します。

連携先

  • gbrain doctor — frontmatter_integrity サブチェックは audit と同じ件数を報告します。frontmatter_repairable は gbrain repair frontmatter で修正できるファイル数を数え、git_held_files は保留中のファイルを一覧表示します。
  • skills/maintain/SKILL.md — brain の健全性に関する、より広範な監査です。ほかの種類の問題が疑われる場合は、このスキルの後に実行してください。
  • gbrain lint — スキルファイルの lint に関する重複ルールです(CLI コマンドであり、スキルではありません)。lint の出力に含まれる frontmatter-* ルール名は、このスキルの検証対象に由来します。

出力形式

監査の概要(簡潔でエージェント向け):

Frontmatter audit — 17 issue(s) across 1 source(s)

[default] /Users/me/brain
  17 issue(s)
    MISSING_CLOSE: 8
    NESTED_QUOTES: 5
    NULL_BYTES: 4
  sample:
    people/jane.md — MISSING_CLOSE
    companies/acme.md — NESTED_QUOTES
    (+ 12 more)

Fix with: gbrain frontmatter validate /Users/me/brain --fix

JSON エンベロープ(--json が渡された場合):

{
  "ok": false,
  "total": 17,
  "errors_by_code": { "MISSING_CLOSE": 8, "NESTED_QUOTES": 5, "NULL_BYTES": 4 },
  "per_source": [
    {
      "source_id": "default",
      "source_path": "/Users/me/brain",
      "total": 17,
      "errors_by_code": { "MISSING_CLOSE": 8, "NESTED_QUOTES": 5, "NULL_BYTES": 4 },
      "sample": [{ "path": "people/jane.md", "codes": ["MISSING_CLOSE"] }]
    }
  ],
  "scanned_at": "2026-04-25T22:30:00.000Z"
}

gbrain frontmatter validate <path> --json は、ソースごとではなくファイルごとの結果をキーとする、同様のエンベロープを返します。

防止 — 有効な frontmatter の作成

これは最も重要なセクションです。 壊れた frontmatter を修正するのは大切です。そもそも壊れた frontmatter を作成しないことは、それ以上に大切です。

YAML 配列(過去に最も多かったエラーの原因)
# Correct: single-quoted YAML flow (canonical form gbrain emits)
tags: ['yc', 'w2025', 'ai']

# Correct: unquoted scalars (fine when values have no special chars)
tags: [yc, w2025, ai]

# Correct: block style
tags:
  - yc
  - w2025

# Tolerated post-v0.37.5.0 but non-canonical: JSON-style double quotes
tags: ["yc", "w2025"]

# Broken: mixed JSON objects and strings (invalid YAML)
tags: [{"name": "sports"}, "posterous"]

以前はなぜ問題が発生していたのか: v0.37.5.0 より前は、バリデーターがエスケープされていない " の文字数を数え、3 個以上ある行にフラグを付けていました。tags: ["yc", "w2025"] のようなフローシーケンスには、仕様上エスケープされていない " が 4 個あります。これは有効な YAML ですが、単純なカウンターは誤ってフラグを付けていました。ある brain では、1 回の doctor 実行でこのようなケースが 6,981 件見つかりました。v0.37.5.0 では、疑わしい値にフラグを付ける前に js-yaml.safeLoad で解析するため、JSON 形式の配列が NESTED_QUOTES を引き起こすことはなくなりました。

それでも標準形式で記述すべき理由: 自動修正エンジン(gbrain frontmatter validate --fix)と推論されたフロントマターのシリアライザーは、どちらも tags: / aliases: に単一引用符の YAML を出力します。新しいコンテンツを標準形式で記述すると、ソースファイルのスタイルが一貫し、--fix の実行による差分がなくなります。

よくある LLM の落とし穴: tags: [${items.map(t => JSON.stringify(t)).join(', ')}] のようなコードは、tags: ["yc", "w2025"] を生成します。アポストロフィが含まれる場合のフォールバックを用意した単一引用符を使ってください:tags: [${items.map(t => t.includes("'") ? JSON.stringify(t) : "'" + t + "'").join(', ')}]。または、標準形式の YAML を出力できる YAML ライブラリを使用してください。

引用符付きスカラー
# Correct: single quotes for values with special chars
title: 'My "Quoted" Title'

# Correct: double quotes when value has apostrophes
title: "Men's Fashion Guide"

# Broken: double quotes wrapping inner double quotes
title: "My "Quoted" Title"
引用符で囲む場合
  • 引用符なしでも、単純な値なら問題ありません:type: person、batch: w2025
  • 値に : " ' # [ ] { } | > & * ! ? , が含まれる場合、または @ で始まる場合は、引用符で囲んでください
  • 単一引用符が安全なデフォルトです
  • 値自体にアポストロフィが含まれる場合に限り、二重引用符を使ってください

エラーが発生した場合

gbrain のエラー code、終了コード、[AGENT] ブロック、または通知ブロックが発生した場合は、エージェントオペレータープロトコルに従ってください。このスキル固有の対応:

  • gbrain frontmatter validate が 1 で終了する場合:エラーが見つかったことを示します(クラッシュではなく、それが実行結果です)。errors_by_code を解析し、ソースごとの件数を報告してください。
  • 修正を実行する前に、変更対象のファイル数を伝え、ユーザーの同意を得てください。修正によって .bak バックアップが作成されます。また、YAML_PARSE エラーは常に自動修復できるとは限りません。
  • gbrain sync がファイルを保留する場合(invalid_frontmatter、frontmatter_slug_conflict、file_too_large、content_rejected):同期自体は成功しています。保留内容を確認し(gbrain sources status <id>)、上記の「保留されたファイル」の手順に従ってください。
  • put_page が新しいファイルが保留されているページへの書き込みを拒否する場合:ファイルを修復してください。再試行しても、書き込みは再び拒否されます。

アンチパターン

ユーザーに確認せず MISSING_OPEN や EMPTY_FRONTMATTER を自動修正しないでください。 これらは通常、人間の作成者がページを書き始めたものの、完成させていないことを意味します。未完成の下書きを囲む --- マーカーを黙って挿入するのは適切ではありません。

監査を読む前に、「doctor を成功状態にする」ために --fix を使わないでください。 SLUG_MISMATCH は、gbrain がパスからスラッグを導出するため、手動確認の対象として明示されます。不一致は通常、ユーザーが意図的にファイル名を変更したことを意味します。スラッグフィールドの自動削除が適切なのは、名前変更が意図的だったと確認できた場合だけです。

.bak バックアップを省略しないでください。 .bak は、git 管理されていない brain リポジトリにおける安全性の保証です。修正の実行後に .bak ファイルが蓄積しても、それはバグではなく機能です。ユーザーは差分を確認し、問題がないと判断したらバックアップを削除できます。

ソースが登録されていない brain に対して audit を実行しないでください。 CLI は「監査対象の登録済みソースがありません」と問題なく返しますが、移行では skipped: no_sources のフェーズ結果が出力されます。手動でパスを走査して補わないでください。ソースを gbrain sources add で登録するのが正しい対処です。

git リポジトリ外の brain ディレクトリには、pre-commit フックをインストールしないでください。 インストールコマンドは、そのようなディレクトリを 1 行のメモとともに自動的にスキップします(ホストリポジトリのサブディレクトリである brain は問題ありません。フックはホストのルートにインストールされ、そのサブディレクトリに対象が限定されます)。「スキップされました。git リポジトリではありません」と表示されても書き込み時に検証したい場合は、cron のスケジュールで audit コマンドを使用してください。

コメント