wiki-lint について
wiki-lint は Obsidian wiki の健全性を監査するスキルです。構造、メタデータ、リンク、情報の出所などを検査し、問題への対処方法を示します。
主な機能
- 01孤立ページとリンク切れの検出
- 02必須 frontmatter 項目の確認
- 03古い内容や主張の矛盾の検出
- 04インデックス、出所情報、タグ群の監査
- 05可視性タグと昇格候補の確認
活用シーン
- 01大規模な Obsidian vault の定期監査
- 02リンク切れ、孤立ページ、インデックスのずれの特定
- 03出所情報と機密情報の分類確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ ar9av/ obsidian-wiki --skill wiki-lintインストール後、Claude Code で/wiki-lintを入力して読み込まれたか確認します。
詳細
Wiki Lint — ヘルス監査
Obsidian wiki のヘルスチェックを実施します。目的は、時間の経過とともに wiki の価値を損なう構造上の問題を見つけて修正することです。
スキャンを始める前に: llm-wiki/SKILL.md の Retrieval Primitives 表に従ってください。ページ全体を読むよりも、フロントマターを対象に絞った grep や、セクションを指定した読み取りを優先してください。大規模な Vault で、Lint のためにすべてのページをやみくもに読むことこそ、このフレームワークが避けるために作られたやり方です。
開始前
執筆プロファイル: 自然言語の Markdown を作成または書き直す前に、llm-wiki/SKILL.md の Writing Profile Resolution セクションを読み、適用してください。フレームワークのスキーマ、出典情報、安全性、および操作固有の要件が優先されます。
WRITING.md の設定は、生成する統合レポートにのみ適用してください。決定論的な検出結果と修正には、既存の形式を維持してください。
- 設定を解決する —
llm-wiki/SKILL.mdの Config Resolution Protocol(インラインの@nameによる上書き → CWD から上位へ.envを探す → グローバル設定 → 設定を促す)に従ってください。これにより、OBSIDIAN_VAULT_PATHと、設定されている場合はOBSIDIAN_ALLOWED_LIFECYCLES、OBSIDIAN_ALLOWED_RELATIONSHIP_TYPES、OBSIDIAN_REQUIRED_TRUST_FIELDS、OBSIDIAN_SCHEMA_SOURCEの値が得られます。 - オーナーのルールを読む —
$OBSIDIAN_VAULT_PATH/AGENTS.mdが存在する場合は、スキーマを解釈する前に読み込んでください。オーナーのルールはフレームワークのデフォルトより優先されます。 - 有効なスキーマを組み立てる — スキーマソースの参照先と、有効な必須/任意のフロントマター、ライフサイクル値、関係タイプ、出典マーカーを記録してください。フレームワークの値はデフォルトです。オーナーの拡張と緩和された必須要件をそのまま維持してください。オーナーの型をフレームワークの型に決して強制変換しないでください。
index.mdを読み、ページの全一覧を確認しますlog.mdを読み、最近の活動の状況を確認します
決定論的なチェックには、有効なスキーマを明示的に渡してください。たとえば、各オーナー拡張を --allow-lifecycle/--allow-relationship-type で追加し、信頼情報の必須要件を繰り返し指定する --required-trust-field に置き換え、権威ある定義元を --schema-source "$OBSIDIAN_VAULT_PATH/AGENTS.md" で指定します。JSON レポートの schema ブロックは、検出結果を確定する前に組み立てたスキーマと一致していなければなりません。
スキーマの優先順位は、CLI フラグ > 解決済みの環境変数/設定値 > フレームワークのデフォルトです。ライフサイクルと関係タイプの拡張は追加方式です。使用前に、すべての上書き値から余分な空白を取り除いてください。明示的に設定された空または空白のみの値、およびカンマ区切りリスト内の空の項目は、すべてフェイルクローズとしてください。有効なライフサイクル、関係タイプ、必須フィールド、または権威ある定義元の参照先として扱ってはいけません。デフォルトを使う場合は、変数そのものを削除してください。
obsidian-wiki が PATH 上にある場合は、obsidian-wiki lint "$OBSIDIAN_VAULT_PATH" --json(上記と同じスキーマ上書きフラグを指定)を優先し、JSON の findings をヘルスレポートに反映してください。CLI を利用できない場合は、以下の grep ベースのチェックを続けてください。バイナリを必須にしてはいけません。
JSON レポートに findings.snapshot_mismatch が含まれている場合は、該当ページをレポートに列挙してください。snapshots: の欠落やずれは、必須フロントマターの欠落ではありません(セクション 3 で対象とするのは title、category、tags、sources、created、updated のみです)。スナップショットのずれを修正するために sources: を書き換えてはいけません。obsidian-wiki snapshots apply --from-json <lint.json> を実行して(ドライラン)、プレビューを表示し、ユーザーから明示的な確認を得た後にのみ --apply を指定してください。適用すると、引用符で囲まれた "[[_raw/_archived/stem|stem]]" のリスト項目(表示テキスト付きのネイティブ Property リンク)が書き込まれます。wiki-lint --consolidate は、この検出結果を適用しません。
Lint チェック
以下のチェックを順番に実行してください。検出結果は随時報告してください。
対象範囲: すべてのチェックで _archives/、_raw/、_readouts/、.obsidian/ を除外してください。これらには、固定されたスナップショット、未処理のステージング用ドラフト、派生した読み取りデータ(wiki-narrate による保存物)が含まれます。これらはナレッジグラフのページではないため、孤立ページ、フロントマター、リンクのチェック対象外です。
1. 孤立したページ
被リンクのウィキリンクがないページを探します。どこからもつながっていない知識の孤島です。
確認方法:
- Vault 内のすべての
.mdファイルを Glob で検索します - 各ページについて、Vault 内のほかのページから
[[page-name]]の参照を Grep で検索します - 被リンクがないページ(
index.mdとlog.mdを除く)は孤立したページです
修正方法:
- どの既存ページから孤立したページにリンクすべきかを特定します
- 適切なセクションにウィキリンクを追加します
2. 壊れたウィキリンク
存在しないページを指す [[wikilinks]] を探します。
確認方法:
- すべてのページを対象に
\[\[.*?\]\]を Grep で検索します - リンク先を抽出します。最初の
|(エイリアス)または#(見出し/ブロックアンカー)以降を削除し、表のセル内でエスケープされた\|の後に残る末尾のバックスラッシュを取り除きます - 拡張子が添付ファイルの種類(
.png、.jpg、.gif、.svg、.webp、.pdf、.canvas、.base、音声、動画)であるリンク先はスキップします。これはページリンクではなく埋め込みであり、このチェックで照合する.mdの一覧には含まれないためです - すべてのドットを拡張子として扱わないでください。
[[Node.js]]、[[Next.js]]、[[v1.2 release notes]]は、名前にたまたまドットが含まれているページリンクです。これらを除外すると、実際に壊れているリンクを見落とすうえ、リンク先のページが孤立しているように見えてしまいます - 残った文字列から明示的な
.mdのサフィックスを削除し、対応する.mdファイルが存在するか確認します
修正方法:
- リンク先の名前が変更されている場合は、リンクを更新します
- リンク先が存在するべき場合は、ページを作成します
- リンクが間違っている場合は、削除するか修正します
3. フロントマターの不足
すべてのページに、title、category、tags、sources、created、updated が必要です。
確認方法:
- すべてのページを全文読み込むのではなく、ファイル冒頭の
^---を対象にフロントマターのブロックを Grep で検索します - 必須フィールドが欠けているページを検出します
修正方法:
- 妥当なデフォルト値を設定して、欠けているフィールドを追加します
3a. 要約の不足(軽微な警告)
すべてのページに summary: フロントマターフィールドを含めることが望ましいです。1~2文、200文字以内にしてください。これにより、安価な検索(例:wiki-query のインデックスのみモード)でページ本文を開かずに済みます。
確認方法:
- Vault 全体を対象に、フロントマター内の
^summary:を Grep で検索します summary:がないページを検出します。ただし、エラーではなく軽微な警告として扱います。このフィールドが導入される前の古いページは問題ありません。このチェックは、新しいページを書き込む際に取り込みスキルが要約を入力するよう促すためのものです- 要約が200文字を超えるページも検出します
修正方法:
- ページを再取り込みするか、短い要約(ページの内容を1~2文で説明したもの)を手動で記述します
4. 古い内容
参照元に対して updated のタイムスタンプが古いページです。
確認方法:
- ページの
updatedタイムスタンプを、参照元ファイルの更新日時と比較します - ページが最後に更新された後に参照元が変更されている場合、そのページを検出します
日付のない主張(行単位)。 obsidian-wiki lint は undated_claims を報告します。これは、日付が行内にないまま、古くなる可能性のある数や金額(スター数、ユーザー数、顧客数、ダウンロード数、取引数、MRR/ARR)を述べている行です。日付付きの見出しの下にある行、journal/ 内のページ、名前が YYYY-MM-… のページ、コード、引用ブロックは対象外です。警告のみで、失敗にはなりません。それぞれの行について、数値を再確認して (as of YYYY-MM-DD) と記載するか、最新の数値が掲載されている場所へのリンクに置き換えるか、日付付きの見出しの下に履歴として移動します。
5. 矛盾
ページ間で食い違っている主張です。
確認方法:
- 関連するページを読み、主張を比較する必要があります
- タグを共有しているページや、相互に多く参照されているページに注目します
- 「しかし」「対照的に」「にもかかわらず」といった表現を探し、すでに認識されている矛盾と、認識されていない矛盾を見分けます
修正方法:
- 矛盾を記載した「未解決の質問」セクションを追加します
- 両方の情報源と、それぞれの主張を参照します
6. インデックスの整合性
index.md が実際のページ一覧と一致しているか確認します。
確認方法:
index.mdに記載されたページと、ディスク上の実際のファイルを比較しますindex.mdの要約が、引き続きページの内容と一致しているか確認します
7. 出典情報のずれ
ページの内容のうち、どの程度が推論で、どの程度が抽出されたものか、正確に示されているかを確認します。規約については、llm-wiki の Provenance Markers セクションを参照してください。
確認方法:
provenance:ブロック、または^[inferred]/^[ambiguous]マーカーを含む各ページについて、文や箇条書きの数と、それぞれのマーカーで終わる項目の数を数えます- おおよその割合(
extracted、inferred、ambiguous)を算出します - 次の基準を適用します:
- AMBIGUOUS > 15%:「推測への依存が大きい」としてフラグを付けます。主張の7分の1でも本当に不確かであれば、出典をより厳密にするか、
synthesis/に移す必要があることを示しています - INFERRED > 40% で frontmatter に
sources:がない:「出典のない統合」としてフラグを付けます。ページは関連付けを行っていますが、引用できるものがありません - ハブページ(wikilink の被リンク数上位10ページ)で INFERRED > 20%:「出典情報に疑問のある、アクセス数の多いページ」としてフラグを付けます。ハブページの誤りは、そこにリンクするすべてのページに波及します
- ずれ:ページに
provenance:frontmatter ブロックがある場合、いずれかの項目が再計算値から 0.20 を超えて異なるときにフラグを付けます
- AMBIGUOUS > 15%:「推測への依存が大きい」としてフラグを付けます。主張の7分の1でも本当に不確かであれば、出典をより厳密にするか、
provenance:frontmatter とマーカーのどちらもないページはスキップします。規約上、完全に抽出されたものとして扱います
修正方法:
- 曖昧な内容が多い場合:出典から再取り込みして不確かな主張を解消するか、推測に基づく内容を
synthesis/ページに分割します - 出典のない統合の場合:frontmatter に
sources:を追加するか、ページを統合内容として明確に示します - INFERRED > 20% のハブページの場合:再取り込みを優先します。ここでの誤りは最も広範囲に波及します
- ずれがある場合:再計算値に合わせて
provenance:frontmatter を更新します
8. タグクラスターの分断
同じタグが付いたページ同士が実際にリンクされているかを確認します。タグはトピッククラスターを示します。これらのページが互いを参照していない場合、クラスターは分断されており、つなぎ合わせるべき知識の孤島になっています。
確認方法:
- 5ページ以上に付けられている各タグについて:
n= このタグが付いたページ数actual_links= このタググループ内の任意の2ページ間にある wikilink の数(両方向を確認)cohesion = actual_links / (n × (n−1) / 2)
- cohesion < 0.15 かつ n ≥ 5 のタググループにフラグを付けます
修正方法:
- 分断されたタグを対象に
cross-linkerスキルを実行します。不足しているリンクが提示され、挿入されます - タググループが大きく(n > 15)、それでも分断されている場合は、より具体的なサブタグへの分割を検討します
9. 可視性タグの整合性
visibility/ タグが正しく付けられていること、また必要な箇所で知らないうちに付け漏れていないことを確認します。
確認方法:
- タグのない PII パターン: ページ本文から、機密データを示すことが多いパターンを Grep します。
password、api_key、secret、token、ssn、email:、phone:に実際の値(フィールドの説明ではない)が続く行が対象です。一致したページにvisibility/piiまたはvisibility/internalがない場合、分類ミスの可能性が高いとしてフラグを付けます sources:のないvisibility/pii:visibility/piiタグが付いたページには、必ずsources:frontmatter フィールドが必要です。出典情報がなければ、その分類を検証できません。sources:がないvisibility/piiページにフラグを付けます- タクソノミー内の可視性タグ:
visibility/タグはシステムタグのため、_meta/taxonomy.mdに含めてはいけません。見つかった場合は設定ミスとしてフラグを付けます。これらを含むページでは、タグの5件上限に数えられてしまいます
修正方法:
- タグのない PII パターンの場合:ページの frontmatter のタグに
visibility/piiを追加します(個人データではなくチームのコンテキストに関する内容の場合はvisibility/internalを追加します) sources:がない場合:出典情報を追加するか、ユーザーに確認します。自動入力はしないでください- タクソノミーに混入している場合:
_meta/taxonomy.mdからvisibility/エントリを削除します
10. その他の昇格候補
misc/ 内で、プロジェクトとの関連性が十分に高まり、昇格候補となったページを見つけます。
確認方法:
$OBSIDIAN_VAULT_PATH/misc/*.mdを Glob します- 各ページの
affinityフロントマター項目を読み取ります - いずれか1つのプロジェクトのスコアが 3 以上のページにフラグを立てます
修正方法:
- affinity スコアが古いと思われる場合(例:wikilink が多数あるページで
affinity: {}となっている場合)は、まずcross-linkerスキルを実行します - 昇格するには、ページを
projects/<project-name>/references/(またはその他の適切なカテゴリ)に移動し、categoryフロントマターを更新して、promotion_statusを削除し、バックリンクを更新するために Vault を grep します
12. 信頼度とライフサイクルのスキーマ
信頼度とライフサイクルのフロントマター・スキーマを適用します(llm-wiki/SKILL.md の「信頼度とライフサイクル」セクションを参照)。
モードは2つあります。
--check(デフォルト、読み取り専用)— エラーと警告を報告します--consolidate— 個別に承認された構造上のメンテナンスを適用する場合がありますが、base_confidenceを書き換えることはありません
信頼度は意味に基づく判断です。決定論的なツールは、ソース文字列だけから独立した根拠の系譜や、ページ全体にわたる主張の網羅性を推測できません。そのため、信頼度の自動化では、明示的に承認された手動の信頼台帳を検証します。URL の数をレビューの代わりにすることはありません。
ルール 12a — lifecycle 列挙値の検証
確認方法: 全ページのフロントマターで ^lifecycle: を grep します。有効なライフサイクル値の集合(フレームワークのデフォルト:{draft, reviewed, verified, disputed, archived})に含まれない値にフラグを立てます。
修正方法: 該当なし(ライフサイクル状態を設定するのは人間だけにしてください)
ルール 12b — base_confidence の範囲
確認方法: 全ページのフロントマターで ^base_confidence: を grep します。設定されている値が [0.0, 1.0] の範囲外であればフラグを立てます。項目がない場合は、有効なオーナーのスキーマで必須とされている場合に限りフラグを立てます。
修正方法: 該当なし(値が誤っている場合はスキルの計算ミスを意味します。手動修正のために提示してください)
ルール 12c — 古いページのレポート(計算によるオーバーレイ)
古さは保存されず、読み取り時に計算されます:is_stale = (today − updated) > 90 days。
確認方法: 各ページのフロントマターから updated: を読み取り、is_stale を計算します。古い場合は、lifecycle: も確認します。以下を報告します。
lifecycle: verifiedの古いページには、より目立つ注釈を付けます(信頼度が高いにもかかわらず、誤っている可能性があるため、最も危険です)- その他の古いページはすべて、通常の警告として報告します
修正方法: --fix は lifecycle を書き換えません。再取り込みで updated が更新されると、古さは自動的に解消されます。
ルール 12c-2 — 不正なライフサイクル遷移
ライフサイクルの列挙値は自由形式のラベルではなく、状態機械です。obsidian-wiki lint は、各ページの現在の lifecycle と、直近のレビュー時に _meta/trust-ledger.json に記録された値を比較して、illegal_lifecycle_transitions を報告します。
フラグ対象: draft に戻るすべての状態遷移(draft を設定するのは ingest のみです)、および archived からのすべての遷移(終端状態です。復元は人間が意図的に削除して再作成します)。
フラグ対象外: draft → verified。台帳のスナップショットはまばらなため、2回のレビューの間に正当な中間状態 reviewed を経ていた可能性があります。フラグを立てると、正当な履歴にも警告が発生してしまいます。
デフォルトでは警告し、--strict-trust を指定すると失敗します。台帳のエントリが lifecycle フィールドの導入以前のページには基準値がないため、警告なしでスキップされます。
修正方法: 該当なし — ページが禁止された遷移を行っている場合、スキルが設定すべきでない lifecycle を書き込んだか、人間による遷移の記録が必要であることを意味します。人間による解決のために提示してください。
ルール 12d — 置換関係の整合性
確認方法: superseded_by: "[[target]]" が設定された各ページについて、以下を確認します。
- 対象ページが存在すること
- 対象ページ自体が
archivedではないこと(循環または連鎖した置換がないこと) - 循環がないこと(A が B を置換し、B が A を置換する)
superseded_byが設定されているのにlifecycle != archivedの場合、警告します(状態に一貫性がありません)
修正方法: 該当なし — 人間による解決のためにフラグを立てます
ルール 12e — 信頼度レビューの完全性
確認方法: まず、決定論的な台帳バリデーターを実行します。
obsidian-wiki trust-check "$OBSIDIAN_VAULT_PATH" --strict --json --pretty
CI と定期ゲートには --strict を使用します。古い警告、未レビューの警告、ページが見つからない警告がある場合、終了コードが 0 以外になります。--strict を指定しない場合、trust-check は読み取り専用のレポートコマンドとして動作し、台帳に重大なエラーがある場合、またはスコアが一致しない場合にのみ終了コードが 0 以外になります。
承認済み台帳は _meta/trust-ledger.json にあります。各エントリーには、人間がレビューしたスコアと、ページの重要なコンテンツおよびエビデンスのメタデータの SHA-256 フィンガープリントが記録されます。このフィンガープリントでは、変動する記録情報(updated、base_confidence、ライフサイクルの遷移フィールド)は除外されるため、タイムスタンプのみの編集ではレビューが再度必要になりません。
結果は次のように解釈します。
reviewed— 現在の重要コンテンツのフィンガープリントと保存済みスコアが、どちらも承認済みレビューと一致しています。ソース文字列から再計算しないでください。stale— 本文、要約、ソース、来歴、タグ、または関係性が変更されています。新たに手動で来歴と主張の網羅性をレビューしてください。unreviewed— ページに承認済み台帳エントリーがありません。手動レビューが必要です。score_mismatches— 重要コンテンツは引き続き一致していますが、保存済みのbase_confidenceが承認済みの値と異なります。Lint を失敗させてください。errors— 台帳データが不正または欠落しています。Lint を失敗させてください。
別途承認されたリポジトリ全体のレビューでは、承認された状態を明示的に記録します。
obsidian-wiki trust-record "$OBSIDIAN_VAULT_PATH" \
--all --reviewed-at "<ISO-8601 timestamp>" --approved --json --pretty
別途承認された、特定の古いページまたは未レビューのページのみを対象とするレビューの後は、それらのエントリーのみを更新します。
obsidian-wiki trust-record "$OBSIDIAN_VAULT_PATH" \
--page "concepts/example.md" --page "skills/example.md" \
--reviewed-at "<ISO-8601 timestamp>" --approved --json --pretty
--approved は、記録するすべてのスコアを人間が承認したことを意味します。これはワークフロー上の表明であり、暗号署名ではありません。_meta/trust-ledger.json をバージョン管理下に置き、台帳の変更をマージする前に人間による差分レビューを必須にしてください。--all が有効なのは、リポジトリ全体のレビュー後のみです。一部のレビューには繰り返し指定可能な --page を使用し、無関係な古いページは未解決のままにしてください。警告を黙らせるためだけに trust-record を実行してはいけません。
古いページまたは未レビューのページに対する手動再計算プロトコル:
- ページを重要な主張に分解し、各主張をエビデンスに対応付けます。
- 依存するエビデンスを独立した来歴にまとめます。同じリポジトリのファイルやコミット、同じタスクチェーン内の再試行、取得したソースとそのスナップショット、重複したメモリ、親タスクと子タスクは、それぞれ 1 件として数えます。
llm-wikiのバケットを使用して、独立した来歴ごとにレビュー済みの品質を割り当てます。- ベーススコアを計算してから、ページ全体の主張の網羅性を評価します。この計算式は出発点であり、自動的に目標とする値ではありません。
- 結果を
raise、keep、lower、またはrepair firstに分類します。base_confidenceを変更する、または台帳を更新する前に、承認を必須としてください。
修正方法: 信頼度を自動修正する方法はありません。明示的に承認された厳密なパッチのみを適用し、その範囲を確認してから、レビュー済みの台帳状態のみを更新します。--consolidate で base_confidence を書き換えてはいけません。
現在の適用ルール
フレームワークのデフォルトでは、予約されていないすべてのコンテンツページに、[0.0, 1.0] の範囲内の有限な base_confidence と、文書化されたライフサイクル値が必要です。オーナースキーマでは、どちらかのフィールドを任意にできます。フィールドに値がある場合は引き続き検証されます。信頼性フィールドの欠落または不正、台帳データの不正、必須台帳の欠落は、重大なエラーです。有効な信頼性フィールドがあるものの承認済み台帳エントリーがない新しいページは unreviewed となり、承認済みページに対する重要な変更は stale となります。
出力への追加項目
Wiki Health Report に追加します。
### Confidence/Lifecycle Issues (N found)
- `concepts/foo.md` — missing `lifecycle` field (warning: Phase 1)
- `entities/bar.md` — `lifecycle: stalestate` is not a valid enum value
- `concepts/scaling.md` — `base_confidence: 1.4` is out of range [0.0, 1.0]
- `synthesis/old-analysis.md` — STALE (last updated 2025-10-01, 182 days ago) lifecycle=verified ⚠️ HIGH PRIORITY
- `concepts/outdated.md` — STALE (last updated 2025-11-15, 137 days ago) lifecycle=draft
- `entities/tool-v1.md` — `superseded_by: [[entities/tool-v2]]` but lifecycle=draft (expected archived)
- `concepts/drift-example.md` — confidence review stale: material fingerprint changed; manual lineage + coverage review required
- `entities/mismatch.md` — confidence mismatch: stored=0.80, approved=0.59
LINT ログエントリーに追加します。
- [TIMESTAMP] LINT ... lifecycle_issues=N
13. 型付きリレーションシップの妥当性
relationships: フロントマターブロックを検証します。relationships: ブロックがないページはスキップします。このフィールドは任意です。
フレームワークのデフォルト型: extends、implements、contradicts、derived_from、uses、replaces、related_to。オーナー拡張を適用した後の有効な集合と照合して検証します。
確認方法:
- すべての Vault ページのフロントマターから
^relationships:を grep します relationships:ブロックがある各ページについて、ページ本文全体ではなくフロントマターを読み取ります- ブロック内の各エントリについて、次の項目を確認します。
- 型の検証 — 上記の許可された集合にない
type:の値をすべて報告します - リンク先の欠落 —
target:文字列から[[と]]を取り除き、正規化(小文字化、スペースをハイフンに置換、.mdを削除)して、そのパスに対応する.mdファイルが Vault に存在するか確認します。解決できないリンク先を報告します。 正規化する前に、最初の|(エイリアス)または#(見出し/ブロックアンカー)以降をすべて削除します。パイプでエイリアスを指定したリンク先や、見出しにアンカーしたリンク先は、角括弧内の文字列がファイル名と一致しないだけではリンク切れではありません。 - 自己参照 — 解決されたリンク先がページ自身のノード ID と一致するエントリをすべて報告します
- 型の検証 — 上記の許可された集合にない
修正方法:
- 無効な型:値と有効なスキーマの出典を報告します。フレームワークのデフォルトとオーナー拡張のどちらにも存在しない場合にのみ修正します。有効なオーナー型を
related_toに置き換えてはいけません。 - リンク先の欠落:エントリを更新または削除します。リンク先ページが存在するべき場合は、先に作成します
- 自己参照:エントリを削除します
出力への追加:
### Typed Relationship Issues (N found)
- `concepts/foo.md` — relationships[1]: type "contradication" is not an allowed type (did you mean "contradicts"?)
- `concepts/bar.md` — relationships[0]: target "[[skills/nonexistent-skill]]" resolves to no page in vault
- `entities/baz.md` — relationships[2]: self-reference (target resolves to this page's own id)
LINT ログエントリに追記します:
... relationship_issues=N
14. イベント時点の妥当性
フロントマターの valid_from/valid_until/superseded_by を検証します。3 つとも任意であり、いずれも持たないページはスキップします。
created/updated は取り込み時点を示しますが、これら 3 つは主張自体が真であったイベント時点を示します。valid_until が過去の日付になったページは誤りではなく、履歴情報です。Vault とグラフには残り、デフォルトの検索結果からのみ除外されます。
確認方法:
- すべての Vault ページのフロントマターから
^valid_from:、^valid_until:、^superseded_by:を grep します - いずれかのフィールドがある各ページについて、次の項目を確認します。
- 日付の解析可能性 — 各値は
YYYY-MM-DDまたは完全な ISO 8601 タイムスタンプでなければなりません。それ以外の値をすべて報告します。 - 期間の順序 —
valid_untilがvalid_fromより前のページをすべて報告します - 後継ページの欠落 —
superseded_byから[[/]]を取り除き、最初の|または#以降をすべて削除し、.mdを削除して正規化し、ページが存在するか確認します。解決できないリンク先と自己参照を報告します。
- 日付の解析可能性 — 各値は
obsidian-wiki lint は、これら 3 つの問題を temporal_errors(日付、期間)および superseded_dangling(後継ページ)として報告します。角括弧で囲まれたリンク切れの後継ページは、broken_links にも表示されます。
警告ではなくエラーとして日付を扱う理由: 検索では、解析できない期間は現在有効なものとして扱われます。そのため、報告されない誤記があると、古くなった主張が事実として回答に使われる可能性があります。これは、まさにこのフィールドで防ぐべき問題です。
修正方法:
- 解析できない日付:
YYYY-MM-DDの形式に書き直します。実際の日付が不明な場合は、推測せずフィールドを削除します - 逆転した期間:ページの情報源を確認して、どちらの日付が誤っているかを特定します。決して黙って入れ替えてはいけません
- 後継ページの欠落:置き換え先のページを作成するか、参照先を修正するか、主張が置き換えられていない場合は削除します
- 履歴ページを現在有効な内容に書き換えて「修正」してはいけません。期間を設けた目的である記録が失われます
出力への追加:
### Event-Time Issues (N found)
- `references/gateway-nginx.md` — valid_until (2026-04-01) precedes valid_from (2026-05-01)
- `references/old-limits.md` — valid_until "soon" is not a date
- `references/legacy-auth.md` — superseded_by "[[oauth-rollout]]" resolves to no page in vault
LINT ログエントリに追記します:
... temporal_issues=N
11. 統合の不足
Wikiに欠けている価値の高い統合の機会、つまり多くのページで同時に登場するものの、それらをつなぐ synthesis/ ページがない概念ペアを特定します。
確認方法:
synthesis/内のすべてのページを一覧表示し、それぞれがすでに扱っている概念ペアを([[wikilinks]]またはタイトルから)収集しますconcepts/とentities/から、リンク数の多い概念を10~15個選びます- 各ペアについて、両方にリンクしているページ数を手早く grep で数えます:
rg -l --glob '*.md' "\[\[ConceptA\]\]" "$OBSIDIAN_VAULT_PATH" > /tmp/a.txt rg -l --glob '*.md' "\[\[ConceptB\]\]" "$OBSIDIAN_VAULT_PATH" > /tmp/b.txt comm -12 <(sort /tmp/a.txt) <(sort /tmp/b.txt) | wc -l - 共起数が3以上で、既存の統合ページがないペアに印を付けます
修正方法:
/wiki-synthesizeを実行して、上位の不足箇所を自動的に見つけて埋めます
出力形式
結果を構造化されたリストで報告します:
## Wiki Health Report
### Orphaned Pages (N found)
- `concepts/foo.md` — no incoming links
### Broken Wikilinks (N found)
- `entities/bar.md:15` — links to [[nonexistent-page]]
### Missing Frontmatter (N found)
- `skills/baz.md` — missing: tags, sources
### Stale Content (N found)
- `references/paper-x.md` — source modified 2024-03-10, page last updated 2024-01-05
- `projects/foo.md:28` — undated claim: "GitHub: 6★" (stamp it, link it, or date the heading)
### Contradictions (N found)
- `concepts/scaling.md` claims "X" but `synthesis/efficiency.md` claims "not X"
### Index Issues (N found)
- `concepts/new-page.md` exists on disk but not in index.md
### Missing Summary (N found — soft)
- `concepts/foo.md` — no `summary:` field
- `entities/bar.md` — summary exceeds 200 chars
### Provenance Issues (N found)
- `concepts/scaling.md` — AMBIGUOUS > 15%: 22% of claims are ambiguous (re-source or move to synthesis/)
- `entities/some-tool.md` — drift: frontmatter says inferred=0.10, recomputed=0.45
- `concepts/transformers.md` — hub page (31 incoming links) with INFERRED=28%: errors here propagate widely
- `synthesis/speculation.md` — unsourced synthesis: no `sources:` field, 55% inferred
### Fragmented Tag Clusters (N found)
- **#systems** — 7 pages, cohesion=0.06 ⚠️ — run cross-linker on this tag
- **#databases** — 5 pages, cohesion=0.10 ⚠️
### Visibility Issues (N found)
- `entities/user-records.md` — contains `email:` value pattern but no `visibility/pii` tag
- `concepts/auth-flow.md` — tagged `visibility/pii` but missing `sources:` frontmatter
- `_meta/taxonomy.md` — contains `visibility/internal` entry (system tag must not be in taxonomy)
### Misc Promotion Candidates (N found)
Pages in misc/ that have ≥ 3 connections to a single project and are ready to be promoted:
| Page | Top Project | Affinity Score |
|---|---|---|
| `misc/web-martinfowler-articles-microservices.md` | `obsidian-wiki` | 4 |
### Typed Relationship Issues (N found)
- `concepts/foo.md` — relationships[1]: type "contradication" is not an allowed type
- `concepts/bar.md` — relationships[0]: target "[[skills/nonexistent]]" resolves to no page
### Synthesis Gaps (N found)
Concept pairs that co-occur frequently but have no synthesis page:
| Pair | Co-occurrence | Suggested Action |
|---|---|---|
| [[Caching]] × [[Consistency]] | 5 pages | Run `/wiki-synthesize` |
| [[Testing]] × [[Observability]] | 3 pages | Run `/wiki-synthesize` |
リント後
log.md に追記します:
- [TIMESTAMP] LINT issues_found=N orphans=X broken_links=Y stale=Z contradictions=W prov_issues=P missing_summary=S fragmented_clusters=F visibility_issues=V promotion_candidates=C synthesis_gaps=G relationship_issues=R
問題を自動で修正するか、ユーザーが対処する項目を選べるようにします。
統合モード(--consolidate)
wiki-lint --consolidate によって起動します。レポートのみから実行して報告するモードに切り替わります。これはWikiを定期的に自動修復する「ドリームサイクル」です。
安全プロトコル
必ず最初にドライランを実行します。 書き込みを行う前に、次の手順を実行します。
- 12項目すべてのリントチェックを実行します(上記のステップ1~12)。
- 実行予定の統合作業を構造化リストとして出力します(下記のドライラン出力を参照)。
- ユーザーに
"Apply these N changes? [yes / no / select]"と尋ねます。 - 明示的な確認を得てから書き込みを行います。ユーザーが個別の作業を選択した場合は、その項目のみを適用します。
- ページを統合してはなりません。統合には
wiki-dedupを使用します。リンクの追加、昇格、降格、フラグ付けのみを行います。ここではsnapshot_mismatchを適用してはなりません。これは専用の確認があるスナップショット用CLIで対応します(「開始前」を参照)。
統合作業(確認後、以下の順に実行)
書き込み前のスナップショット — 最初のファイル書き込みの前に、Vault自体がGitリポジトリのルートかどうかを確認します。より大きなリポジトリのサブディレクトリであるだけでは該当しません。そこで git add -A を実行すると、無関係なファイルまで取り込む可能性があるためです。Vaultが独立したGitリポジトリでない場合は、この手順を黙ってスキップします。しつこく確認を促したり、git init を提案したりしてはなりません。
VAULT_REAL_PATH=$(cd "$OBSIDIAN_VAULT_PATH" && pwd -P)
VAULT_GIT_ROOT=$(git -C "$OBSIDIAN_VAULT_PATH" rev-parse --show-toplevel 2>/dev/null || true)
SNAPSHOT_SHA=""
if [ -n "$VAULT_GIT_ROOT" ] && [ "$VAULT_GIT_ROOT" = "$VAULT_REAL_PATH" ]; then
if git -C "$OBSIDIAN_VAULT_PATH" diff --quiet \
&& git -C "$OBSIDIAN_VAULT_PATH" diff --cached --quiet \
&& [ -z "$(git -C "$OBSIDIAN_VAULT_PATH" ls-files --others --exclude-standard)" ]; then
SNAPSHOT_SHA=$(git -C "$OBSIDIAN_VAULT_PATH" rev-parse HEAD)
else
if ! git -C "$OBSIDIAN_VAULT_PATH" add -A; then
echo "Pre-write snapshot failed; abort the skill without writing any vault files." >&2
exit 1
fi
if ! git -C "$OBSIDIAN_VAULT_PATH" commit -m "pre-wiki-lint snapshot" --quiet; then
echo "Pre-write snapshot failed; abort the skill without writing any vault files." >&2
exit 1
fi
SNAPSHOT_SHA=$(git -C "$OBSIDIAN_VAULT_PATH" rev-parse HEAD)
fi
fi
クリーンなリポジトリの場合の分岐では、意図的に git commit を呼び出さないため、「コミットするものがありません」はエラーとして扱われません。git add または git commit が失敗した場合は、Vaultを編集する前に停止します。約束したスナップショットを作成せずに処理を続行してはなりません。
SNAPSHOT_SHA が空でなく、スキルがファイルを書き込む場合は、最終レポートにSHAを含めます。後から加えた変更のうち残しておく価値のあるものがないことを確認したうえで、実行全体を破棄するには、次を実行します。
git -C "$OBSIDIAN_VAULT_PATH" reset --hard "$SNAPSHOT_SHA"
git -C "$OBSIDIAN_VAULT_PATH" clean -fd
アクション1:壊れたwikilinkを修正する
チェック2で見つかった壊れた [[Target]] ごとに、次の処理を行います。
- タイトルまたはファイル名が最も近いページをVault内で検索します(
index.mdのタイトルをGrepで検索します)。 - 一意の最適候補が見つかった場合(編集距離が2文字以下、または同じ語根を持つ場合)は、リンクを書き換えます。書き換え内容を記録します:
[[Oringal]] → [[corrected-page]]。 - 候補がない場合、または曖昧な場合は、プレーンテキストに変換し(
~~[[Target]]~~→Target)、コメント `` を追加します。 - 壊れたリンクを解消するためだけに、新しいページを作成してはなりません。
アクション2:孤立ページに不足している相互参照を追加する
チェック1で見つかった孤立ページ(被リンクがゼロのページ)ごとに、次の処理を行います。
- Vaultの本文で、ページのタイトルまたは別名への言及を検索します(大文字と小文字は区別しません)。
- 別のページで言及が見つかった場合は、プレーンテキストの言及を
[[wikilink]]に置き換えます。 - 孤立ページごとに追加は最大3件までとし、ページにリンクを過剰に追加しないでください。
- この処理の対象は孤立ページのみです。広範囲に実行する
cross-linkerとは異なります。
アクション 3: ライフサイクル状態の修正
以下のルールを自動的に適用します(人間の判断は不要です。文書化された状態機械を強制するものです):
draft→reviewedへの昇格:lifecycle: draftかつcreatedが 30 日より前かつbase_confidence > 0.7のページ。lifecycle: reviewed、lifecycle_changed: <today>、lifecycle_reason: "auto-promoted by wiki-lint --consolidate: age>30d, confidence>0.7"を設定します。verified→staleへの降格: これは状態遷移ではありません —staleは計算されたオーバーレイであり、ライフサイクルの値ではありません。代わりに、is_stale = (today − updated) > 180 daysである verified ページについて、ページ本文の先頭にコールアウトを追加します:> ⚠️ **Stale**: This page was last updated <date>. Verify before relying on it.コールアウトがまだ存在しない場合にのみ追加します。reviewed→verifiedやその他の遷移を変更しないでください — これらは人間のみが行えます。
アクション 4: 階層の降格
tier: supporting(または未設定)で、被リンクが 0 件かつ 90 日以上更新されていないページについて:
tier: peripheralを設定します。- ユーザーが確認できるよう、降格のリストを出力します。
tier: coreのページを自動的に降格しないでください — これらは手動で設定されたものです。
アクション 5: タグの正規化
エイリアスマッピング(例: ml → machine-learning)について _meta/taxonomy.md を読み込みます。各ページについて、tags: frontmatter フィールド内の既知のエイリアスタグを正規形に置き換えます。これは tag-taxonomy の作業のサブセットです — エイリアスの修正のみで、完全な監査は行いません。
アクション 6: 矛盾のコールアウト
互いに矛盾しているとマークされたページのペア(frontmatter の relationships: contradicts、またはチェック 5 でフラグが立てられたもの)について:
- 該当する主張の近くに
> ⚠️ Contradiction flagged with [[Other Page]]コールアウトがすでに存在するかどうかを確認します。 - 存在しない場合は、「Key Ideas」セクションの末尾(「Key Ideas」セクションがない場合は「Open Questions」の前)に追加します。簡潔に保ってください — 1 行で。
- 矛盾を解決しないでください。視覚的にフラグを立てるだけです。
アクション 7: 統合レポートの書き込み
すべてのアクションの後、synthesis/consolidation-<YYYY-MM-DD>.md にレポートを書き込みます:
---
title: Consolidation Report <YYYY-MM-DD>
category: synthesis
tags: [maintenance, consolidation]
sources: []
summary: Auto-generated consolidation report from wiki-lint --consolidate run on <date>.
lifecycle: draft
lifecycle_changed: <date>
tier: peripheral
created: <obsidian-wiki memory now>
updated: <obsidian-wiki memory now>
---
# Consolidation Report — <YYYY-MM-DD>
## Summary
- Broken links fixed: N
- Cross-references added: M
- Lifecycle states updated: K
- Tier demotions: D
- Tags normalized: T
- Contradiction callouts added: C
## Broken Link Fixes
- `concepts/foo.md:12` — [[OldTarget]] → [[correct-target]]
- `entities/bar.md:8` — [[Missing]] → `Missing` (no match found)
## Cross-References Added (orphan rescue)
- `concepts/baz.md` — now linked from: [[concepts/alpha]], [[skills/beta]]
## Lifecycle Updates
- `concepts/old-draft.md` — draft → reviewed (age 45d, confidence 0.74)
- `synthesis/stale-verified.md` — stale callout added (last updated 2025-10-01)
## Tier Demotions
- `concepts/unused-concept.md` — supporting → peripheral (0 links, 120 days stale)
## Tag Normalizations
- `entities/some-tool.md` — `ml` → `machine-learning`
## Contradiction Callouts
- `concepts/scaling.md` — flagged contradiction with [[synthesis/efficiency]]
ドライラン出力(書き込み前に表示)
wiki-lint --consolidate — Dry Run
Planned actions (N total):
[1] Fix broken link: concepts/foo.md:12 [[OldTarget]] → [[correct-target]]
[2] Add cross-ref: concepts/baz.md ← [[concepts/alpha]] (orphan rescue)
[3] Lifecycle: concepts/old-draft.md → reviewed (age 45d, confidence 0.74)
[4] Tier demotion: concepts/unused.md → peripheral (0 links, 112 days stale)
[5] Tag alias: entities/some-tool.md: ml → machine-learning
[6] Contradiction callout: concepts/scaling.md ↔ [[synthesis/efficiency]]
Apply these 6 changes? [yes / no / select by number]
consolidate モードのログエントリ
- [TIMESTAMP] LINT_CONSOLIDATE links_fixed=N orphans_rescued=M lifecycle_updates=K tier_demotions=D tag_fixes=T contradiction_callouts=C report=synthesis/consolidation-YYYY-MM-DD.md
Vault 書き込み後の QMD リフレッシュ
QMD は検索インデックスであり、信頼できる情報源ではありません。$QMD_WIKI_COLLECTION が空または未設定の場合は、このステップをスキップしてください。このスキルが vault の markdown を書き込みまたは書き換えた後にのみ実行してください。QMD リフレッシュが失敗した場合でも、vault の変更をロールバックしないでください。QMD のステータスは別途報告してください。
$QMD_CLI が設定されている場合はそれを使用し、そうでない場合は qmd を使用します。
${QMD_CLI:-qmd} update
出力にベクトルが必要、または埋め込みが古い可能性があると表示された場合は、次を実行します:
${QMD_CLI:-qmd} embed
次のいずれかでコレクションを検証します:
${QMD_CLI:-qmd} ls "$QMD_WIKI_COLLECTION"
または、特定のページパスがわかっている場合:
${QMD_CLI:-qmd} get "qmd://$QMD_WIKI_COLLECTION/<page>.md" -l 5
次のいずれかを記録します:
QMD refreshed: update + embed + verifiedQMD refreshed: update only + verifiedQMD skipped: QMD_WIKI_COLLECTION unsetQMD skipped: qmd CLI unavailableQMD failed: <short error summary>