INVARA について
INVARA は、宣言されたエンジニアリング上の制約を観測可能な証拠に基づいて検査し、モデルを使わずに判定します。シェルを使えるコーディングエージェントを利用する開発者向けで、変更範囲を限定して確認します。ソフトウェアの正しさを証明するものではありません。
主な機能
- 01作業前に契約を封印
- 02ファイルダイジェストとコマンド結果で制約を判定
- 03PASS、BLOCK などの判定を記録
- 04判定の再実行と追記型履歴の確認
- 05変更前後の振る舞いを検証
- 06修復を単位ごとに管理
活用シーン
- 01リファクタリング中に指定ファイルを保護
- 02変更後に宣言済み条件を確認
- 03移行前後の振る舞いを比較
- 04チェックに合格した修復単位だけを保持
MCP 対応
ローカル MCP サーバーは、タスクの封印と判定、判定の一覧表示と記録、ハッシュチェーンの再構築、判定の再実行を行う 6 つのツールを提供します。封印済み契約で指定されたチェックを実行し、判定経路にモデルは含まれません。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
6掲載時のツール一覧 · 3 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| db | string | いいえ | 判定データベース。デフォルトは .runtime/verify.db です。 |
| root | string | いいえ | リポジトリのルート。デフォルトは作業ディレクトリです。 |
| commit | boolean | いいえ | 判定をハッシュチェーンに追加します。デフォルトは false(ドライラン)です。 |
| task_id | string | はい | 判定する封印済みタスク。 |
| timeout_s | integer | いいえ | チェックごとのタイムアウト(秒)。デフォルト:900。 |
詳細
INVARA
AI が構築したソフトウェアのエンジニアリング上の不変条件。
INVARA は Claude Code、Codex、およびシェルを使えるあらゆるコーディングエージェントに対応しています。宣言された制約を観測可能な証拠に照らして検証しますが、ソフトウェアの正しさを証明するものではありません。
seal before work -> agent does the work -> judge
|
PASS / BLOCK / UNVERIFIABLE / HUMAN_REVIEW
お使いの環境に合った方法から始めてください。
- Claude Code:
/plugin marketplace add Jujitae/invaraを実行し、続けて/plugin install invaraを実行して、同梱のエディター/プラグイン環境をインストールします。 - Codex またはシェルを使える別のエージェント:
uvx --from invara==0.3.0 invara listを実行するか、python -m pip install invara==0.3.0で継続的にインストールします。 - エージェントに伝える: AI エージェント向けクイックスタートのコピー&ペースト用手順を使い、受け取った判定をそのまま保持します。
最初に得られるのは判定であり、エージェントによる自己申告ではありません。PASS は、宣言されたすべてのチェックが約束どおりの結果を返し、保護対象のパスに変更がなかったことを意味します。BLOCK、UNVERIFIABLE、HUMAN_REVIEW は、そのままの意味で扱います。解釈し直して成功とみなすことはできません。
現在の公開リリース:0.3.0。ステータス:アルファ版。INVARA Free は一般公開されており、INVARA Pro は別途提供される有料製品です。INVARA は自律的な認可機能でも、エンタープライズ向けのコンプライアンス制御でもありません。
0.3.0 における変換保証、Gen 1
2 つのローカル CLI ワークフローで、リファクタリングや移行に関して宣言された動作範囲をチェックできるようになりました。
invara assureは、同等性マニフェストを使って既存の変更前/変更後のペアを比較し、最小化された反例を検索できます。invara repairは、修復を一度に 1 つずつ管理し、宣言されたチェックで受け入れられた場合にのみ、その単位を保持します。
Gen 1 で測定するのは、マニフェストで宣言された入力、観測結果、ポリシー、主張に限られます。PASS はその範囲内での判定であり、正しさ、セキュリティ、またはバグがないことを一般的に証明するものではありません。これらのワークフローは、ユーザーが名前を指定したコマンドをユーザーの権限で実行します。外部へのネットワーク接続は行いません。HTTP プローブが接続できるのは、セッション用にマニフェストが起動したループバックサービスのみです。
CLI ガイドとマニフェストガイドから始めてください。合成例と表示レポートは fixtures/ と docs/transformation-assurance/samples/ にあります。
これは何ではないか
インストール手順に進む前に、ここを読んでください。意図的に短くしています。上記の約束を支える言葉は「正しい」ではなく「検証可能」です。
INVARA はソフトウェアの正しさを証明しません。 宣言された制約を観測可能な証拠に照らして検証します。
具体的には、次のとおりです。
- コードベースを調査しません。 コードの品質、アーキテクチャが成り立つか、テストが適切かどうかを確認することはありません。粗悪な土台に新しい階層を積み上げても、その階層が宣言された仕様どおりに作られていれば、判定は
PASSになります。 - バグを見つけません。 テストスイートを実行する完了チェックの強さは、そのテストスイート次第です。INVARA が報告するのは終了コードであり、カバレッジについて判断することはありません。
- 何を約束すべきかを決めません。 契約を記述するのはユーザーです。弱い契約から得られるのは弱い
PASSであり、契約はそのまま保存されるため、誰でもその弱さを確認できます。 - サンドボックスではありません。 完了チェックはコマンドであり、ユーザーの権限で実行されます。内容を読んでいない契約を確定しないでください。
- 意図を評価しません。
intentは文章であり、作業がその意図どおりだったかを確認するものはありません。拘束力を持つのはチェックです。 - AI コード生成ツールでも、LLM によるコードレビューボットでもありません。 判定の経路にモデルは一切ありません。
主張する範囲は限定されています。実際にシステムが行うのは、次のことです。
この変更が、自ら交わした約束を守ったかどうかを独立して判定します。
CLI を使った最初の判定を詳しく
設定は不要です。API キー、サービス、アカウントは必要ありません。Python 3.12+ と uv があれば使えます。
uvx --from invara==0.3.0 invara list
または、インストールして使う場合:
python -m pip install invara==0.3.0
パッケージには実行時依存関係が一切ありません。そのため、標準ライブラリのみが取り込まれます。バージョンを固定したインストールでは、インストール済みの INVARA のバージョンが表示され、pip list には追加の実行時パッケージが表示されません。
チェックアウトから使う場合も同じプログラムですが、まずインストールしてください。ソースは src/ の下にあるため、リポジトリのルートで python -m invara を実行しても、実行するものが見つかりません。
pip install -e .
python -m invara list
公開前のリリース候補検証
同梱のプラグインと配布パッケージでは、同じ6つの MCP ツールを公開する必要があります。メンテナーが新しいパッケージバージョンを公開する前に、そのホイールをビルドし、リポジトリのクリーンな環境での検証を実行してください。新しい仮想環境を作成し、インデックスを使わずにそのホイールだけをインストールして、stdio 経由で MCP サーバーを起動し、正確なツール一覧を確認します。その後、封印、判定、一覧表示、ログ記録、チェーンの再構築、判定の再生を行います。
python -m pip wheel --no-deps . --wheel-dir .runtime/invara-dist
python scripts/verify_fresh_install.py --wheel-dir .runtime/invara-dist --plugin-root plugin
これはリリース候補の検証であり、公開コマンドではありません。CI ワークフローでは、候補となるプルリクエストごとに、Windows と Ubuntu でそれぞれ独立して実行されます。
1. 作業の前に契約を書く
変更するリポジトリの隣にある task.json:
{
"task_id": "2026-08-17-tidy-the-parser",
"intent": "Speed up the CSV parser without changing what it accepts",
"constraints": [
{
"kind": "paths_unchanged",
"paths": ["tests/test_parser.py"],
"reason": "a speedup that edits its own test is not a speedup"
}
],
"done_when": [
{
"id": "suite",
"command": ["python", "-m", "pytest", "-q"],
"expect_exit": 0,
"reason": "the whole suite"
}
]
}
invara seal task.json
封印では、判定結果が分かる前に、保護対象パスのダイジェストが取得されます。この順序こそが保証のすべてです。
2. 作業する
3. 判定する
invara judge 2026-08-17-tidy-the-parser # dry run
invara judge 2026-08-17-tidy-the-parser --commit # record it
BLOCK: 1 protected path(s) changed: tests/test_parser.py: changed
(a speedup that edits its own test is not a speedup)
decided by: constraint_breaks
これが最初の判定です。以下はすべて詳細です。
4つの判定
| 判定 | 意味 | 終了コード |
|---|---|---|
BLOCK | 保護対象パスが変更された、または完了チェックに失敗した | 1 |
UNVERIFIABLE | チェックをまったく実行できなかった。未チェックは合格ではありません | 2 |
HUMAN_REVIEW | マシンチェックには合格したものの、人による確認が必要だと宣言されたものがある | 0 |
PASS | すべてのチェックが約束どおりの結果を返し、すべての保護対象パスのバイト列が同一である | 0 |
制約違反があれば、他のすべてに優先します。変更しないと約束したものに触れた実行は、部分的に問題ないとは言えません。
BLOCK という1つの判定には、2つのルールが含まれています。変更された保護対象パスと、期待どおりの結果を返さなかったチェックは、同じ問題ではありません。そのため、判定にはどちらのルールで決まったかも記録されます。これは判定に用いた証拠に基づいて命名され(constraint_breaks、failed、unrunnable、needs_human、passed)、judge と log に表示されます。この機能が追加される前に記録された判定には記録がなく、後から付け加えられることもありません。
封印では、受け入れるより多くを拒否します
seal は、作業に失敗判定を下せない契約を書き込みません。完了条件がないタスク、確認するコマンドがない条件、保護対象パスがない契約(「何でも変更できるタスクが、何かを尊重したとは言えない」)、重複するチェック ID、存在しない保護対象パス、そして最も重要な、すべての条件が人に判断を委ねる契約は拒否されます。
これが単なるお墨付きではない理由です。証拠が誰かの「はい」だけなら、契約は存在しません。
その他のコマンド
invara init print a task.json template for this repository
invara list sealed tasks and their latest verdict
invara log <task_id> every verdict this task has ever had
invara show <task_id> the contract, exactly as sealed
invara replay <task_id> recompute a recorded verdict and compare it
invara chain rebuild both hash chains
「この判定は再現可能だったか?」に答えるのが invara replay です。記録された時点の観測結果から再計算します。リプレイ機能が追加される前に記録された判定は、推測する代わりに no_current_stored を返して拒否されます。
判定は .runtime/verify.db に保存されます(移動するには --db を使います)。契約は一度封印され、その後何度でも判定できます。履歴は追記のみで、チェーン状につながれます。
エディター内
このツールの対象として想定している購入者は、ターミナルを開きません。そのため、同じパッケージに MCP サーバーが含まれており、Claude Code プラグインとして単独で動作します。
/plugin marketplace add Jujitae/invara
/plugin install invara
このプラグインには INVARA のソースが含まれ、python -m で実行されます。必要なのは Python 3.12+ だけです。uv もネットワークも、実行時の依存関係も不要です。サーバーが起動しない場合、/invara:doctor が Python の存在を前提とせずに環境を診断します。既知の無言で失敗するケースは、Python がインストールされていない Windows です。この場合、Microsoft Store の python エイリアスが起動後に終了し、終了コード 9009 と 7 バイトの標準エラー出力(Python )を返します。この終了は INVARA のコードが実行される前に起きます。プラグインが書き込む設定は次のとおりです。
{
"mcpServers": {
"invara": {
"type": "stdio",
"command": "python",
"env": {
"PYTHONPATH": "${CLAUDE_PLUGIN_ROOT}/src"
},
"args": ["-m", "invara.mcp"]
}
}
}
6 つのツール — invara_seal、invara_judge、invara_list、invara_log、invara_chain、invara_replay。これらは前述のコマンドであり、判定の定義は何も変わりません。判定は今もファイルダイジェストと終了コードから計算され、実行されるチェックは封印済みのコントラクトにあらかじめ指定されたものだけです。また、エージェントが作業完了を宣言するためのフィールドは、今もどこにもありません。エージェントはここで判定を求めることはできます。しかし、判定を下すことはできません。
ここでの invara はローカルなラベルです。好きな名前を付けてください。サーバーの正式な識別子は io.github.Jujitae/invara です。MCP レジストリでの登録名であり、レジストリ経由で解決するクライアントがサーバーを見つける際に使う名前です。ただし、上記のキーとしては使えません。claude mcp add は「名前に使用できるのは英字、数字、ハイフン、アンダースコアだけです」と応答します。
これはサンドボックスではなく、この仕組みによってサンドボックスになるわけでもありません。invara_seal はタスクファイルを受け取り、そのファイルにコマンドが指定されており、判定時にそれらを実行します。タスクファイルを書き込めるエージェントは、それらのコマンドを実行させることができます。これはエージェントがすでに持っているシェルの権限を超えるものではありませんが、後から気づくより、ここで明記しておくほうがよいでしょう。
決定性
同じリポジトリの状態、同じコントラクト、同じ環境であれば、判定も同じになります。判定はファイルダイジェストとコマンドの終了コードだけから計算され、それ以外は関与しません。モデルは処理に含まれず、判定に時計も使われません。
主張ではなく、2026-08-17 に測定しました。コントラクト 2026-08-17-route-discovery を、変更のないツリーに対して 4 分間隔で 2 回判定しました。各回で 2,021 テストのスイートを含む 7 つのチェックを実行しました。どちらの実行も同じステータスと同じ理由の文字列を返し、両方の行がチェーンに記録されています。
$ invara log 2026-08-17-route-discovery
2026-08-17 09:17 UTC PASS
7 check(s) passed and 6 protected path(s) are unchanged
2026-08-17 09:21 UTC PASS
7 check(s) passed and 6 protected path(s) are unchanged
信頼して使う前に、ご自身のコントラクトで同じことを試してください。
ここで重要なのは「環境」という言葉です。以下の最初の失敗談を参照してください。ローカルで合格し CI で失敗したコントラクトは、決定性がなかったわけではありません。環境が 2 つ異なっており、INVARA はそれぞれを正しく報告しました。判定を再現可能にしたい場合は、完了コマンドを再現可能にしてください。
失敗の記録
これらは、このツールを構築し、使用する中で実際に起きたことです。成功例しか示さない検証ツールは、「何も信用するな」と自ら告げているその根拠だけは信用するよう求めていることになるため、ここに記載しています。
環境の汚染。 コントラクトは作成したマシンでは合格しましたが、CI では失敗しました。ツリーはクリーンでしたが、環境はクリーンではありませんでした。シェルでPYTHONIOENCODINGが設定され、子プロセスに継承されており、完了コマンドはそれがあったからこそ動作していました。現在、検証の実行にはenv -u PYTHONIOENCODINGを使用しています。ツリーがクリーンでも、環境がクリーンとは限りません。
自らを壊した封印。 新しいクローンでチェックアウトした際、封印済みのオントロジーファイルがCRLFに書き換えられたため、SHA-256が一致しなくなりました。何も変更されていないことを証明するためだけのファイルが、自らの封印に失敗しました。修正したのはダイジェストのルールではなく、.gitattributesです。ダイジェストは正しかったのです。
最初の判定はUNVERIFIABLEで、それが正解でした。 subprocessは実行ファイルの解決にcwdを使用しないため、完了コマンドが見つかりませんでした。判定は正しかったものの、ツールは役に立ちませんでした。この2つの事実はどちらも記録されています。バグだったのはそのうち一方だけです。
自分を作った作業に合格できませんでした。 INVARAが初めて封印したコントラクトは、INVARAを構築する作業でした。結果はUNVERIFIABLE、続いてPASS、さらにPASSでした。この3つはすべて.runtime/verify.dbに残っており、invara logで確認できます。
由来
この設計は、同じプライベートリポジトリにある姉妹エンジンを元にしています。証拠が存在する前にコントラクトを封印し、取り消せないものは作成せず、観測された記録だけを評価し、その結果を連鎖させます。「世界についての主張」を「エージェントの作業」に置き換えれば、同じ仕組みが適用できます。
INVARAはプライベートな作業用リポジトリ(WIE)内で構築され、実際に使われています。このソースにとってそれが何を意味するかについては、PROVENANCE.mdを参照してください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。