mcpField
F
facts

facts

github.com/av開発206112 回インストール21 週間前に更新
リポジトリ

facts について

factsは、`.facts`ファイルにプロジェクトの事実を記録し、その内容を検証するコマンドラインツールです。シェルコマンドによるチェックに加え、手動の事実をAIエージェントに任意で確認させられます。

主な機能

  1. 01`.facts`ファイルへの事実の記録
  2. 02シェルコマンドによる事実の検証
  3. 03手動の事実のAIエージェントへの委任
  4. 04タグやセクションによる事実の整理

活用シーン

  1. 01プロジェクトの期待動作の仕様化
  2. 02開発中の反復的な検証
  3. 03手動の事実のAIエージェントによる確認

インストール

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

$npx skills add https://github.com/av/facts --skill facts

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

詳細

facts

事実駆動型開発のための CLI です。プロジェクトで何が真であるべきかを指定し、現実がそれと一致しているか検証できます。

プロジェクト:https://github.com/av/facts

インストール

facts がインストールされていない場合は、次のいずれかでインストールします。

curl -fsSL https://raw.githubusercontent.com/av/facts/main/install.sh | sh
npm install -g @avcodes/facts
pipx install facts-cli

facts --version で確認します。コマンドは常に facts です。npx facts は使わないでください。

基本的な考え方

.facts ファイルは、プロジェクトに関する原子的な真実の記述を並べたフラットなリストです。各事実には、それを検証するシェルコマンドを任意で設定できます。ファクトシートは仕様(何が真であるべきか)とドキュメント(何が真であるか)の両方の役割を果たします。違いは、どちらの方向から作業するかだけです。

- the API returns JSON
- label: project builds
  command: cargo build
- label: tests pass
  command: cargo test
  tags: [ci, core]

形式は以上です。単純な事実にはプレーンな文字列を、コマンド、タグ、明示的な ID が必要な場合はマッピングを使います。使用できるマッピングのキーは id、label、command、tags のみです。

基本コマンド

推奨する短縮エイリアス(追加の引数はすべてそのまま渡されます):

  • ll = list --light — 最もよく使う「ざっと確認する」ビュー(Markdown の見出し+薄い色の ID)
  • ls = list
  • rm = remove
  • at <id> <tag> = edit <id> --add-tag <tag>(複数の ID と、タグの後に指定する --label / --new-id などに対応)
  • rt <id> <tag> = edit <id> --remove-tag <tag>

これらは、日常の作業やエージェントでの利用において、特に効果の高いショートカットです。

すべてを表示:

facts ll
facts ll --tags "not implemented"
facts ll --has-command
facts list --light                      # or the alias: facts ll

検証:

facts check                             # default: command-facts only; manual stay ?
facts check --tags "ci"
facts check --id abc                    # check a single fact by ID
facts check --section cli/check         # check one section
facts check --agent                     # opt in: .config agent or PATH preset
facts check --agent claude              # opt in: specific agent
facts check --no-agent                  # explicit skip (redundant with default)
facts check --has-command               # check only facts with commands
facts check --manual --agent claude     # check only manual facts with agent
facts check --strict                    # fail on unverified manual facts (CI)
facts check --strict --agent claude -q  # CI: verify everything, fail on gaps
facts check -q                          # quiet: exit code only (for CI)
facts check -v                          # verbose: show agent prompts and output

check は主なフィードバックループです。まずファイルをリントし(構造上のエラーがあれば中断します)、次にコマンド付きの事実をすべて実行して、成功/失敗/手動の結果を報告します。頻繁に実行してください。終了コード 0 は、コマンド付きの事実がすべて成功したことを意味します。エージェントが手動の事実を検証して失敗を見つけた場合、または --strict を使用した場合(未検証の手動の事実をすべて失敗として扱います)を除き、手動の事実は終了コードに影響しません。

手動の事実(出力の ?)は、あなたが確認する必要があります。 これらにはコマンドがありません。関連するコードを読んで検証します。? の事実ごとに、記述内容を読み、コードを確認してから、1 行の理由を添えて PASS または FAIL を報告してください。確認せずに「手動 N 件」と報告するのは認められません。これらの事実は、重要な動作を記述しているため存在します。

エージェントによる検証に向けてプロジェクトを設定:

facts config set agent claude           # persist agent choice in .facts
facts config set batch-size 5           # how many facts per agent call
facts config show                       # see current config
facts config rm agent                   # remove a config key

事実を追加:

facts add "users can sign up" --section features/auth
facts add "signup returns 201" --command "curl -s -o /dev/null -w '%{http_code}' localhost:3000/signup | grep 201" --section features/auth

事実を編集/タグ付けする(ライフサイクルの移行):

facts at <id> "implemented"          # most common: quick add tag
facts rt <id> "spec"                 # quick remove tag
facts at <id> "spec" --new-id xyz    # extra flags still work
facts edit <id> --label "corrected statement"
facts edit <id> --command "new check command"
facts edit <id> --remove-command            # convert back to manual fact
facts edit <id> --remove-command --add-tag "draft"  # demote to manual + draft

タグをすべて置き換える --tags より、at/rt(または長い形式の --add-tag/--remove-tag)を優先してください。--tags はすべてのタグを通知なく置き換えます。検証コマンドを取り除いて事実を手動の事実に戻すには、--remove-command を使います(ライフサイクルをまたいで格下げする場合に便利です)。

事実を削除:

facts rm <id>     # or the long form: facts remove <id>

新しいプロジェクトのひな形を作成:

facts init

すべてのフラグの説明については、facts <command> --help を実行してください。

facts の仕組み

ファイル: デフォルトは .facts です。追加のシートには意味のある名前を付けます(cli.facts、api.facts)。プロジェクトのルートにあるすべての *.facts ファイルが自動的に検出されます。

セクション: Markdown の見出し(#、## など)によって階層的なセクションが作成され、パス(例:cli/subcommands)で指定できます。セクションは項目を追加すると作成され、最後の fact を削除すると削除されます。

タグ: フィルタリングに使う @word トークンです。プレーンな文字列ではインラインで記述します(- some fact @mvp)。マッピングでは tags: キーを使います。表示と ID のハッシュ化の前に、ラベルから取り除かれます。ブール式でフィルタリングします:--tags "mvp and not blocked"。

ライフサイクルタグ: 次の 3 つの既知のタグがエージェントのワークフローを制御します:

  • @draft — 粗いアイデア。詳細化と細分化が必要です
  • @spec — 明確かつ実行可能で、実装の準備ができています
  • @implemented — 正しく、コードによって裏付けられています
  • タグのない fact は、コードベースと照合して検証された確かな情報です

ライフサイクルは @draft → @spec → @implemented と進みます。各コンパニオンスキルが 1 つの遷移を担当します。

ID: すべての fact には、ラベルのハッシュから生成される短い ID(3 文字以上)が付与されます。ラベルが変わらない限り、ID は安定しています。上書きするには --id または --new-id を使います。

検証: コマンドはプロジェクトのルートで $SHELL(フォールバックは sh)を使って実行されます。終了コード 0 は、fact が成立することを示します。コマンドは高速かつ冪等になるように記述してください。チェックのたびに実行されます。

設定: .config fact(明示的な id: .config)には、メインの .facts ファイルにプロジェクトレベルの設定を保存します。既知のキーは agent(プリセット名またはシェルテンプレート)と batch-size(エージェントの呼び出しあたりの fact 数)です。facts config set/get/show/rm で管理します。

エージェントによる検証

facts check は、コマンドのない手動の事実を AI エージェントに委任して検証できます。エージェントはコードベースを読み、各事実が成り立つかどうかを報告します。

オプトインのみ: エージェントによる検証は --agent を指定した場合にのみ実行されます。指定しない場合、手動の事実は ? のままです。

--agent を指定した場合の解決順序(最初に一致したものを使用します):

  1. --agent <value> — プリセット名、または %p を含むシェルテンプレート
  2. 引数なしの --agent — .config agent キー(facts config set agent claude で設定)
  3. 設定がない状態で引数なしの --agent — プリセット順に、PATH 内の既知のエージェントバイナリを検索

プリセット: claude、codex、pi、droid、opencode、mi。それぞれコマンドテンプレートに対応します(例:claude は claude -p %p になります)。カスタムテンプレートでは、プロンプトのプレースホルダーとして %p を使います:--agent "my-agent run %p"。

仕組み:

  1. コマンドのある事実を先に実行します(順次実行し、結果を即時出力)
  2. 残りの手動の事実をまとめて処理します(デフォルトでは1バッチあたり10件。--batch-size または .config batch-size で変更可能)
  3. 各バッチは、事実の ID とラベルを含む単一のプロンプトとしてエージェントに送信されます
  4. エージェントの出力から、判定用の XML タグが解析されます

判定形式 — 呼び出されたエージェントとして応答する場合、事実ごとに XML タグを1つ返してください:

<fact-verdict id="abc">PASS</fact-verdict>
<fact-verdict id="def">FAIL the feature is missing from auth.rs</fact-verdict>

ルール:

  • 成り立つ事実には PASS、成り立たない事実には FAIL reason を使用します
  • FAIL の後には1行の理由を記載します
  • 事実ごとに判定を1つ出力し、省略しないでください
  • id 属性は、プロンプト内の事実 ID と一致させてください
  • 解析前に Markdown のフェンスと ANSI コードが除去されます
  • ID が複数回現れた場合は、最後の判定が採用されます
  • 一致する判定がない事実は「未解決」として報告されます(失敗として扱われます)

フラグ:

  • --no-agent — エージェントによる検証をスキップします(--agent を指定しない場合のデフォルト動作)
  • --id <ID> — 指定した事実のみを確認します(繰り返し指定可能で、すべてのフィルターと併用できます)
  • --section "path" — セクションパスで絞り込みます(大文字・小文字を区別しないサブパス一致。子セクションも含みます)
  • --tags "expr" — ブール式によるタグフィルターです(例:"ci and not draft")
  • --search "expr" — セクション、ラベル、タグを対象に全文検索します
  • --file "name" — 特定の .facts ファイルに絞り込みます
  • --has-command — 検証コマンドのある事実のみを確認します(手動の事実はスキップ)
  • --manual — 手動の事実のみを確認します(検証コマンドなし)。--agent との併用に便利です
  • --depth N — セクションのネスト深度を制限します
  • --timeout <secs> — コマンドおよびエージェントの各バッチに対するタイムアウト
  • --strict — 未検証の手動の事実を失敗として扱います(終了コードは0以外)。すべての事実をコマンドまたはエージェントで検証する必要がある CI パイプラインでは必須です
  • --quiet / -q — 出力せず、終了コードのみを返します(0 = すべて成功)
  • --verbose / -v — デバッグ用にエージェントのプロンプトと生の出力を表示します

良い事実の書き方

事実には、プロジェクトが持つファイルや使用するライブラリではなく、プロジェクトが何をするか、つまりその動作、機能、契約を記述してください。判断基準は、エージェントが事実一覧だけを使ってプロジェクトを再実装した場合、正しく動作するかどうかです。

  • 動作を記述する — コードに何があるか(「認証モジュールがある」)ではなく、ユーザーから見て何が起こるか(「期限切れのトークンは 401 で拒否される」)を記述します
  • 原子的である — 1つの事実につき1つの真実だけを記述し、個別に検証できるようにします
  • 宣言的である — 何をすべきかではなく、何が真実かを記述します(「PostgreSQL を使用する」であり、「PostgreSQL をセットアップする」ではありません)
  • 安定している — コミットのたびに変わる内容は避けます(「テストが成功する」であり、「テストが47件ある」ではありません)
  • 反証可能である — この事実が成り立たない、不完全な実装を想定できるようにします

依存関係やファイル構成などの構造的な事実は補足情報であり、主な内容ではありません。「X ライブラリを使用する」「Y ディレクトリがある」ばかりの事実一覧では、プロジェクトが実際にどう動作するのかをエージェントに伝えられません。

適切な検証コマンドは、高速で、冪等性があり、1つのことを検証します。完全なビルドを実行するより、test -f、grep -q、短いスクリプトによるチェックを優先してください。

良いファクトの条件

以下の品質は、それぞれ実際のエージェント管理プロジェクトで見られた失敗パターンの逆を表しています。

  • 仕様を先に定義する — ファクトはコードの後ではなく、コードより先に記述されています。ファクトシートは仕様であり、変更履歴ではありません。作業の完了は、新たなファクトを追加してすでに完了した作業を記録するのではなく、@implemented を付けて記録します。
  • 振る舞いを示すラベル — ラベルは、ユーザーや呼び出し元が観察できる内容を表します。ソースファイル名、行番号、ブランチ名、カバレッジ率は、ファクトのラベルに含めません。これらはテストで扱う内容です。
  • ブラックボックステスト — コマンドは外部からテストします。ツールを実行し、API を呼び出し、出力を確認します。コマンドが変数名、関数シグネチャ、特定の文字列位置を求めてソースファイルを解析する場合は、振る舞いをテストするよう書き直します。
  • 独立した価値 — ファクトを削除すると、何かが失われる必要があります。既存のテストがすでに同じ主張を検証している場合、そのファクトは単なる中継ラッパーです。別の主張を記述するか、省略します。
  • 継続的に整理する — ファクトを追加する前に、既存のファクトがすでにその振る舞いを網羅しているか確認します。関連するファクトは統合し、ファクトシートが際限なく増えるのを防ぎます。1 つのファイルが約 80 個を超えるファクトを含む場合は、分割が必要です。
  • コントラクト単位 — コードパスごとではなく、機能のコントラクトごとにファクトを 1 つ定義します。同じエンドポイントの成功、エラー、エッジケースの各パスを説明するファクトが 3 つある場合は、エンドポイントのコントラクトについての 1 つのファクトにまとめます。

ドメイン用語

メインの .facts ファイルにある ## domain セクションでは、プロジェクトの主要なエンティティとその関係を定義します。これらもファクト、つまり原子的な真実の記述ですが、特定の振る舞いではなく概念モデルを説明します。

エンティティファクトでは、概念の名前と定義を記述します。一般的な形式は a <Name> is <definition> です。 関係ファクトでは、エンティティ間のつながりを記述します。定義済みのエンティティ名を使い、自然な宣言文で記述します。厳密な文法はありませんが、つながりを具体的に示す必要があります。

## domain
- a FactSheet is a parsed *.facts file containing sections and facts
- a Section is a heading-delimited group of facts, nestable via heading depth
- a Fact is an atomic truth statement: a label, optional command, optional tags
- a FactSheet contains a preamble and nested Sections
- check validates command-bearing Facts by running them in the project root
- Tags filter Facts via boolean expressions

ファクトシート全体で、これらの名前を一貫して使用します。ドメインセクションはメインの .facts ファイルにあります。facts-discover によって作成され、facts-refine によって洗練され、実装中に新しい概念が生まれた場合は facts-implement によって拡張されます。

エージェントのワークフロー

作業開始時 — 必ず最初に実行します:

facts ll                                # read the full spec (skim view)
facts check                             # see what holds and what doesn't

コードを書く前に、ファクトシートで状況を把握します。ファクトシートは、プロジェクトがどのような状態であるべきか、何がすでに検証済みかを示す信頼できる情報源です。

仕様を定義する(最も一般的なユーザーの意図): ユーザーが「ファクトに取り組む」「ファクトを追加する」「仕様を定義する」と言う場合、すでに何が真実かを監査するのではなく、何が真実であるべきかを共同で定義したいという意味です。

facts add "users can sign up" --section features/auth --tags "draft"
facts add "signup returns 201" --command "curl -s ..." --section features/auth --tags "spec"
  • プロジェクトがどのような状態であるべきかをユーザーと話し合います
  • まだ粗いアイデアは @draft として追加し、後で正確な仕様に磨き上げます
  • 正確で実行可能なファクトは @spec として追加します。これらは実装の準備ができています
  • @draft や @spec のファクトは削除しないでください。これらは今後実現する作業を表しています
  • 現状に合わせて同期するようユーザーから明示的に求められない限り、facts-discover を実行しないでください

ライフサイクルの進捗を追跡する:

facts ll --tags "draft"                 # rough ideas to refine (ll = list --light)
facts ll --tags "spec"                  # ready to implement
facts ll --tags "implemented"           # done
facts ll --tags "not implemented"       # all remaining work
facts check                             # verify

コーディング作業中の正確性を保つ: 機能を追加するときは、対応するファクトも追加します。バグを修正するときは、関連するファクトが引き続き成立することを確認します。コードを削除するときは、古くなったファクトも削除します。ファクトを追加する前に、既存のファクトシートがその振る舞いをすでに網羅しているか確認します。似たファクトを増やすのではなく、統合します。

facts check                             # find failing facts
facts at <id> "implemented"             # tag done (alias for edit --add-tag)
facts rm <id>                           # remove obsolete facts
facts add "new truth" --section foo     # add discovered truths

関連スキル

各スキルは、ライフサイクルの移行を 1 つ担当します。

  • facts-discover — コードベースをスキャンし、すべてのファクトをライフサイクルの段階(@draft、@spec、@implemented)に分類します。振り分けや初期設定に使用します。
  • facts-refine — @draft のファクトを取り上げ、ユーザーとともに正確な @spec ファクトへと磨き上げます。ドラフトを明確にする必要があるときに使用します。
  • facts-implement — @spec のファクトを取り上げてコードに実装し、その後 @implemented を付けます。仕様の実装準備が整ったときに使用します。

コメント